BrettRToomey / Jobs

A job system for Swift backends.
MIT License
294 stars 22 forks source link

Jobs

Language Build Status codecov codebeat badge GitHub license

A minimalistic job system in Swift, for Swift

Table of Contents

Integration

Update your Package.swift file.

.package(url: "https://github.com/BrettRToomey/Jobs.git", from: "1.1.1")

Getting started 🚀

Creating a new Job is as simple as:

Jobs.add(interval: .seconds(4)) {
    print("👋 I'm printed every 4 seconds!")
}

Intervals ⏲

The Duration enumeration currently supports .seconds, hours, .days and .weeks.

Jobs.add(interval: .days(5)) {
    print("See you every 5 days.")
}

Syntax candy 🍭

It's possible to create a Duration from an Int and a Double.

10.seconds // `Duration.seconds(10)`
4.hours // `Duration.hours(4)`
2.days // `Duration.days(2)`
3.weeks // `Duration.weeks(3)`

Starting a job 🎬

By default, Jobs are started automatically, but if you wish to start one yourself, even at a later point in time, just do the following:

let job = Jobs.add(interval: 2.seconds, autoStart: false) {
    print("I wasn't started right away.")
}
//...
job.start()

Stopping a job ✋

Giving up has never been so easy!

job.stop()

One-off jobs

If you just want to asynchronously run a job, but not repeat it you can use the oneoff functions.

Jobs.oneoff {
    print("Sadly, I'm not a phoenix.")            
}

How about waiting a little?

Jobs.oneoff(delay: 10.seconds) {
    print("I was delayed by 10 seconds.")
}

Error handling ❌

Sometimes jobs can fail, that's okay, we have you covered.

Jobs.add(
    interval: 10.seconds,
    action: {
        throw Error.someError
    },
    onError: { error in
        print("caught an error: \(error)")
        return RecoverStrategy.default
    }
)

Retry on failure ⭕️

By default, jobs will be attempted again after a five second delay. If you wish to override this behavior you must first implement an onError handler and return one of the following RecoveryStrategy cases.

.none //do not retry
.default //retry after 5 seconds
.retry(after: Duration) //retry after specified duration

Here's a small sample:

enum Error: Swift.Error {
  case recoverable
  case abort
}

Jobs.add(
    interval: 1.days,
    action: {
        //...
    },
    onError: { error in
        switch error {
        //we cannot recover from this
        case .abort:
            //do not retry
            return .none

        //we can recover from this
        case .recoverable:
            //... recovery code

            //try again in 15 seconds
            return .retry(after: 15.seconds)
        }
    }
)