{"id":32151863,"url":"https://github.com/happn-app/retryingoperation","last_synced_at":"2025-10-21T10:54:20.865Z","repository":{"id":63911771,"uuid":"118146153","full_name":"happn-app/RetryingOperation","owner":"happn-app","description":"Retrying operations with no persistence, wrapped in a single Foundation Operation, in Swift","archived":false,"fork":false,"pushed_at":"2023-11-17T12:29:50.000Z","size":84,"stargazers_count":12,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-21T10:54:16.665Z","etag":null,"topics":["apple","ios","macos","swift","tvos","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/happn-app.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"License.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-19T16:00:59.000Z","updated_at":"2024-11-19T15:13:55.000Z","dependencies_parsed_at":"2024-05-13T14:58:25.112Z","dependency_job_id":"3833992a-6176-4186-8bc9-58223c2afc8a","html_url":"https://github.com/happn-app/RetryingOperation","commit_stats":null,"previous_names":["happn-tech/retryingoperation"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/happn-app/RetryingOperation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happn-app%2FRetryingOperation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happn-app%2FRetryingOperation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happn-app%2FRetryingOperation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happn-app%2FRetryingOperation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/happn-app","download_url":"https://codeload.github.com/happn-app/RetryingOperation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happn-app%2FRetryingOperation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280248570,"owners_count":26297925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apple","ios","macos","swift","tvos","watchos"],"created_at":"2025-10-21T10:54:19.845Z","updated_at":"2025-10-21T10:54:20.860Z","avatar_url":"https://github.com/happn-app.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Retrying Operations\n![Platforms](https://img.shields.io/badge/platform-macOS%20|%20iOS%20|%20tvOS%20|%20watchOS%20|%20Linux-lightgrey.svg?style=flat) [![SPM compatible](https://img.shields.io/badge/SPM-compatible-E05C43.svg?style=flat)](https://swift.org/package-manager/) [![License](https://img.shields.io/github/license/happn-app/RetryingOperation.svg)](License.txt) [![happn](https://img.shields.io/badge/from-happn-0087B4.svg?style=flat)](https://happn.com)\n\n## What Is It?\n\nAn abstract class for retrying operations.\nThe idea is to provide a clean and easy way to create retrying operations.\nFor instance, if you make an operation to fetch some network resources,\n the operation might fail because there is no Internet right now.\nHowever, Internet might be back soon!\nInstead of bothering your user by telling him there’s no net and he should retry,\n you might want to wait a few seconds and retry the request(s).\n\nThe retrying operation class gives you a way to easily handle the retrying process.\n\n_Note_: Cancelled operations are not retried.\n\n## How to Use It?\n\n`RetryingOperation` is an abstract class.\nIn order to use it you must subclass it.\n\nUsually, when subclassing `Operation`, you either subclass `start()`, `executing`, `finished` and `asynchronous`\n if you want to write an asynchronous operation, or simply `main()` for synchronous operations.\n\nTo subclass `RetryingOperation` correctly, you only have to subclass `startBaseOperation()` and `asynchronous`.\nIn your implementation, you are responsible for starting your operation,\n but you do not have to worry about managing the `executing` and `finished` properties of the operation: they are managed for you.\n\nWhen your operation is finished, you must call `baseOperationEnded()`.\nThe parameters you pass to this method will determine whether the operation should be retried and the retry delay.\nThe method must be called even if the operation is finished because the operation was cancelled\n (even though the retry parameter is ignored if the operation is cancelled).\nIndeed, if your operation is synchronous, the method must be called before the `startBaseOperation()` returns…\n\nWhen your operation is in the process of waiting for a retry, you can call `retryNow()` or `retry(withHelpers:)`\n to bypass the current retry helpers and either retry now or setup new helpers.\n_Note_: If the base operation is already running, never started or is finished when these methods are called,\n nothing is done, but a warning is printed in the logs.\n\n`startBaseOperation()` and `cancelBaseOperation()` will be called from the same, private GCD queue.\nDo **not** make any other assumptions thread-wise about these methods when you’re called.\nAlso note you might not have a working run-loop.\nIf you’re writing an asynchronous operation, you **must** leave the method as soon as possible,\n exactly like you’d do when overwriting `start()`.\n\n## What About Operations I Don’t Own?\n\nUse case: I’m using a framework which provide nice operations.\nI would want to make these operations retryable, but I cannot make them inherit from `RetryingOperation` as I do not own them.\nWhat can I do?\n\nA solution is to use `RetryableOperationWrapper`.\nSee the doc of this class for more information.\n\n## Credits\nThis project was originally created by [François Lamboley](https://github.com/Frizlab) while working at [happn](https://happn.com).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhappn-app%2Fretryingoperation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhappn-app%2Fretryingoperation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhappn-app%2Fretryingoperation/lists"}