Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Queuer is a queue manager, built on top of OperationQueue and Dispatch (aka GCD).

License

NotificationsYou must be signed in to change notification settings

FabrizioBrancati/Queuer

 
 

Repository files navigation

GitHub ReleaseSwift VersionsSwift Platforms

Features

Queuer is a queue manager, built on top ofOperationQueue andDispatch (aka GCD). It allows you to create any asynchronous and synchronous task easily, all managed by a queue, with just a few lines.

Here is the list of all the features:

  • Works on all Swift compatible platforms (even Linux)
  • Easy to use
  • Well documented (100% documented)
  • Well tested (100% of code coverage)
  • Create an operation block
  • Create a single operation
  • Create chained operations
  • Manage a centralized queue
  • Create unlimited queue
  • Declare how many concurrent operation a queue can handle
  • Create semaphores
  • Create and handle schedules
  • Automatically or manually retry an operation
  • Throttling between each automatic operation retry

Requirements

SwiftQueueriOSmacOSmacCatalysttvOSwatchOSvisionOSLinux
3.1...3.21.0.0...1.1.08.0+10.10+9.0+2.0+
4.01.3.08.0+10.10+9.0+2.0+
4.11.3.1...1.3.28.0+10.10+9.0+2.0+
4.22.0.0...2.0.18.0+10.10+9.0+3.0+
5.0...5.102.1.0...2.2.08.0+10.10+9.0+3.0+
5.9...5.103.0.012.0+10.13+13.0+12.0+4.0+1.0+

Installing

SeeRequirements section to check Swift, Queuer, and OS versions.

In yourPackage.swift Swift Package Manager manifest, add the following dependency to yourdependencies argument:

.package(url:"https://github.com/FabrizioBrancati/Queuer.git", from:"3.0.0"),

Add the dependency to any targets you've declared in your manifest:

.target(    name:"MyTarget",     dependencies:[.product(name:"Queuer",package:"Queuer"),]),

Usage

Shared Queuer

Queuer offers a shared instance that you can use to add operations to a centralized queue:

Queuer.shared.addOperation(operation)

Custom Queue

You can also create a custom queue:

letqueue=Queuer(name:"MyCustomQueue")

You can even create a queue by defining themaxConcurrentOperationCount and thequalityOfService properties:

letqueue=Queuer(name:"MyCustomQueue", maxConcurrentOperationCount:Int.max, qualityOfService:.default)

Create an Operation Block

You have three methods to add anOperation block.

  1. Directly on thequeue(orQueuer.shared):

    queue.addOperation{    /// Your task here}
  2. Creating aConcurrentOperation with a block:

    letconcurrentOperation=ConcurrentOperation{ _in    /// Your task here}queue.addOperation(concurrentOperation)

Note

We will see howConcurrentOperation works later.

Chained Operations

Chained Operations areOperations that add a dependency each other.

They follow the given array order, for example:[A, B, C] = A -> B -> C -> completionBlock.

letconcurrentOperationA=ConcurrentOperation{ _in    /// Your task A here}letconcurrentOperationB=ConcurrentOperation{ _in    /// Your task B here}queue.addChainedOperations([concurrentOperationA, concurrentOperationB]){    /// Your completion task here}

You can also add acompletionHandler after the queue creation with:

queue.addCompletionHandler{    /// Your completion task here}

Group Operations

Group Operations areOperations that handles a group ofOperations with a completion handler.

Allows the execution of a block ofOperations with a completion handler that will be called once all the operations are finished, for example:[A -> [[B & C & D] -> completionHandler] -> E] -> completionHandler.It should usually be used with aChained Opetation.

letgroupOperationA=GroupOperation([ConcurrentOperation{ _in            /// Your task A here},ConcurrentOperation{ _in            /// Your task B here}])letconcurrentOperationC=ConcurrentOperation{ _in    /// Your task C here}queue.addChainedOperations([groupOperationA, concurrentOperationC]){    /// Your completion task here}

In this case the output will be the following one:[[A & B -> completionHandler] -> C] -> completionHandler.

Queue States

There are a few method to handle the queue states.

  1. Cancel allOperations in a queue:

    queue.cancelAll()
  2. Pause a queue:

    queue.pause()

Warning

By callingpause() you will not be sure that everyOperation will be paused. If theOperation is already started it will not be on pause until it's a customOperation that overridespause() function.

  1. Resume a queue:

    queue.resume()

Warning

To have a completepause andresume states you must create a customOperation that overridespause() andresume() function.

  1. Wait until allOperations are finished:

    queue.waitUntilAllOperationsAreFinished()

Important

This function means that the queue will blocks the current thread until allOperations are finished.

Synchronous Queue

Setting themaxConcurrentOperationCount property of a queue to1 will make you sure that only one task at a time will be executed.

Asynchronous Operation

ConcurrentOperation is a class created to be subclassed.It allows synchronous and asynchronous tasks, has a pause and resume states, can be easily added to a queue and can be created with a block.

You can create your customConcurrentOperation by subclassing it.

You must overrideexecute() function and call thefinish(success:) function inside it, when the task has finished its job to notify the queue.

For convenience it has aninit function with a completion block:

letconcurrentOperation=ConcurrentOperation{ _in    /// Your task here}concurrentOperation.addToQueue(queue)

Automatically Retry an Operation

AnOperation is passed to every closure, with it you can set and handle the retry feature.

By default the retry feature is disabled, to enable it simply set thesuccess property tofalse. Withsuccess tofalse theOperation will retry until reachesmaximumRetries property value. To let theOperation know when everything is ok, you must setsuccess totrue.

WithcurrentAttempt you can know at which attempt theOperation is.

letconcurrentOperation=ConcurrentOperation{ operationin    /// Your task hereif /* Successful */{      operation.success=true}else{      operation.success=false}}

Manually Retry an Operation

You can manually retry anOperation when you think that the execution will be successful.

AnOperation is passed to every closure, with it you can set and handle the retry feature.

By default the manual retry feature is disabled, to enable it simply set themanualRetry property totrue, you must do this outside of the execution closure. You must also setsuccess totrue orfalse to let theOperation know when is everything ok, like the automatic retry feature.

To let theOperation retry your execution closure, you have to call theretry() function. Be sure to call it at leastmaximumRetries times, it is not a problem if you callretry() more times than is needed, your execution closure will not be executed more times than themaximumRetries value.

letconcurrentOperation=ConcurrentOperation{ operationin    /// Your task hereif /* Successful */{      operation.success=true}else{      operation.success=false}}concurrentOperation.manualRetry=true/// Later on your codeconcurrentOperation.retry()

Caution

If theretry() function is not called, you may block the entire queue.

Manually Finish an Operation

By default theOperation will finish its job when the execution closure is completed.

This means, if you have an asynchronous task insiede the closure, theOperation will finish before the task is completed.

If you want to finish it manually, you can set themanualFinish property totrue and call thefinish(success:) function when the task is completed.

Call thefinish(success:) function withsuccess parameter totrue orfalse to let theOperation know if the task was successful or not. If you don't explicitly set thesuccess parameter, it will be set totrue.

letconcurrentOperation=ConcurrentOperation{ operationin    /// Your asynchonous task here}concurrentOperation.manualFinish=true/// Later on your code in your asynchronous taskconcurrentOperation.finish(success:true)

Caution

If you don't call thefinish(success:) function, your queue will be blocked and it will never ends.

Async Task in an Operation

If you want to use async/await tasks, you need to setmanualFinish totrue in order to be fully in control of theOperation lifecycle.

Note

Read more about manually finish anOperationhere.

letconcurrentOperation=ConcurrentOperation{ operationinTask{        /// Your asynchonous task here        operation.finish(success:true) // or false}    /// Your asynchonous task here}concurrentOperation.manualFinish=true

Caution

If you don't setmanualFinish totrue, yourOperation will finish before the async task is completed.

Scheduler

AScheduler is a struct that uses the GDC'sDispatchSourceTimer to create a timer that can execute functions with a specified interval and quality of service.

letschedule=Scheduler(deadline:.now(), repeating:.seconds(1)){    /// Your task here}

You can even create aScheduler without the handler and set it later:

varschedule=Scheduler(deadline:.now(), repeating:.seconds(1))schedule.setHandler{    /// Your task here}

Withtimer property you can access to allDispatchSourceTimer properties and functions, likecancel():

schedule.timer.cancel()

Semaphore

ASemaphore is a struct that uses the GCD'sDispatchSemaphore to create a semaphore on the function and wait until it finish its job.

Tip

Is recommend to use adefer { semaphore.continue() } right after theSemaphore creation andwait() call.

letsemaphore=Semaphore()semaphore.wait()defer{ semaphore.continue()}/// Your task here

You can even set a custom timeout, default is.distantFuture:

semaphore.wait(DispatchTime(uptimeNanoseconds:1_000_000_000))

It's more useful if used inside an asynchronous task:

letconcurrentOperation=ConcurrentOperation{    /// Your task here    semaphore.continue()}concurrentOperation.addToQueue(queue)semaphore.wait()

Changelog

To see what has changed in recent versions of Queuer, see theCHANGELOG.md file.

Communication

  • If you need help, open an issue.
  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, seeContributing section.

Contributing

SeeCONTRIBUTING.md file.

License

Queuer is available under the MIT license. See theLICENSE file for more info.


[8]ページ先頭

©2009-2025 Movatter.jp