All Projects → jVirus → concurrency-kit

jVirus / concurrency-kit

Licence: MIT License
🚄 Concurrency abstractions framework for Apple Platforms [Task, Atomic, Lock, Operation, etc.].

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to concurrency-kit

Queuer
Queuer is a queue manager, built on top of OperationQueue and Dispatch (aka GCD).
Stars: ✭ 964 (+5570.59%)
Mutual labels:  task, watchos, swift-package-manager
aprenda-swift
Uma lista de conteúdos para você aprender Swift
Stars: ✭ 429 (+2423.53%)
Mutual labels:  apple, watchos, ipados
YACLib
Yet Another Concurrency Library
Stars: ✭ 193 (+1035.29%)
Mutual labels:  task, concurrency, concurrent
Watchshaker
Simple motion detector for ⌚️ (watchOS) shake gesture.
Stars: ✭ 184 (+982.35%)
Mutual labels:  apple, watchos, swift-package-manager
Dots
Lightweight Concurrent Networking Framework
Stars: ✭ 35 (+105.88%)
Mutual labels:  watchos, concurrency, swift-package-manager
treap
A thread-safe, persistent Treap (tree + heap) for ordered key-value mapping and priority sorting.
Stars: ✭ 23 (+35.29%)
Mutual labels:  concurrency, concurrent
SwiftGradients
Useful extensions for UIViews and CALayer classes to add beautiful color gradients.
Stars: ✭ 15 (-11.76%)
Mutual labels:  swift-package-manager, spm
AtomicKit
Concurrency made simple in Swift.
Stars: ✭ 88 (+417.65%)
Mutual labels:  concurrency, mutex
column-text-view-ui
📄 Column Text View is an adaptive UI component that renders text in columns, horizontally [iOS 12, UIKit, TextKit, SwiftUI].
Stars: ✭ 11 (-35.29%)
Mutual labels:  swift-package-manager, spm
Columbus
A feature-rich country picker for iOS, tvOS and watchOS.
Stars: ✭ 23 (+35.29%)
Mutual labels:  watchos, spm
Shift
Light-weight EventKit wrapper.
Stars: ✭ 31 (+82.35%)
Mutual labels:  concurrency, swift-package-manager
WacOS
A Linux distribution that mimics MacOS (modern and classic) iOS, and other Apple operating systems, but is open, customizable, and free to use on non-apple hardware.
Stars: ✭ 18 (+5.88%)
Mutual labels:  apple, ipados
ScrollViewProxy
ScrollViewProxy for SwiftUI on iOS 13 and up
Stars: ✭ 135 (+694.12%)
Mutual labels:  apple, swift-package-manager
Ether
A Command-Line Interface for the Swift Package Manager
Stars: ✭ 86 (+405.88%)
Mutual labels:  swift-package-manager, spm
distlock
The universal component of distributed locks in golang , support redis and postgresql
Stars: ✭ 60 (+252.94%)
Mutual labels:  locks, mutex
futex
File-based Ruby Mutex
Stars: ✭ 14 (-17.65%)
Mutual labels:  concurrency, mutex
DanXi
[Windows / Mac / Android / iOS] Maybe the best all-rounded service app for Fudan University students. 可能是复旦学生最好的第三方校园服务APP。
Stars: ✭ 77 (+352.94%)
Mutual labels:  watchos, ipados
Wells
A lightweight diagnostics report submission system
Stars: ✭ 26 (+52.94%)
Mutual labels:  apple, watchos
Pomosh-iOS-watchOS
🍅Pomosh is your next awesome Pomodoro Technique assistant on 📱iOS and ⌚️ WatchOS 🙌. It's native and lightweight. Uses SwiftUI. has a nice tomato icon and also ready for macOS too🔥
Stars: ✭ 50 (+194.12%)
Mutual labels:  apple, watchos
FitDataProtocol
Swift Implementation the Garmin Flexible and Interoperable Data Transfer Protocol.
Stars: ✭ 32 (+88.24%)
Mutual labels:  swift-package-manager, spm

concurrency-kit Awesome

Build Coverage Platforms Language SPM License

Last Update: 05/January/2020.

If you like the project, please give it a star It will show the creator your appreciation and help others to discover the repo.

✍️ About

🚄 Concurrency abstractions framework for iOS development [Task, Atomic, Lock, etc.].

🔥 Features

  • Atomics - synchronization primitive that is implemented in several forms: Generic, Int and Bool.
    • Fast. Under the hood a mutex (pthread_mutex_lock) that is more efficient than OSSpinLock and faster than NSLock.
    • Throwable. You can safely throw Errors and be able to delegate the handling.
  • Locks - contains a number of locks, such as:
    • UnfairLock - A lock which causes a thread trying to acquire it to simply wait in a loop ("spin") while repeatedly checking if the lock is available.
    • ReadWriteLock - An RW lock allows concurrent access for read-only operations, while write operations require exclusive access.
    • Mutex - Allows only one thread to be active in a given region of code.
  • DispatchQueue+Extensions - extended DispatchQueue, where asyncAfter and once methods add convenience.
  • Task - A unit of work that performs a specific job and usually runs concurrently with other tasks.
    • Tasks can be grouped - meaning that you are able to compose the tasks, similar to Futures & Promises and execute them serially.
    • Tasks can be sequenced - meaning that you are able to compose different groups and execute them concurrently. No need to repeatedly use DispatchGroup (enter/leave).
  • Stateful Operation - is a custom Operation class that supports modern, Swifty state management through the usage of Atomics and Enum types.
  • Thoroughly tested.

📚 Examples

Task

In order to create a Task, you need to simply use the Task struct and the trailing closure syntax:

let uploadingTask = Task { controller in
  uploader(photos) { result in 
    switch result {
      case .success:
        controller.finish()
      case .failure(let error):          
        controller.fail(with error)
    }
  }
}
        
uploadingTask.perform { outcome in
  handle(outcome)
}

You can group the tasks, so the concurrent operations will be performed sequentially, one after another. Then, you can chain a completion closure to handle the outcome:

let filesToUpload = [file, photo, video, xml]

let group = Task.group(fileToUpload)
group.perform { outcome in 
  handle(outcome)
}

Or you can concurrently perform a collection of tasks. They will be executed asynchronously, in parallel (if possible) or concurrently, that is up to the GCD:

let filesToUpload = [file, photo, video, xml]

let group = Task.sequence(filesToUpload)
group.perform { outcome in 
  handle(outcome)
}

Stateful Operation

Operation that has more 'Swifty' state management system, where state is an enum type with a number of possible cases. In order to demostrate the typical usage, let's define a new custom operation for network request:

class NetworkStatefulOperation: StatefullOperation {

  // MARK: - Properties
  
  private let callback: (StatefullOperation?) -> Void
  private let service: NetworkService             
  private let dataHandler: Parsable            
            
  // MARK: - Initializers
  
  init(_ service: NetworkService, _ dataHandler: Parser, callback: @escaping (StatefullOperation?) -> Void) {
    self.service = service
    self.dataHandler = dataHandler
    self.callback = callback
  }
  
  // MARK: - Overrides
  
  override func executableSection() {
    service.dataTask { [weak self] result in 
      self?.dataHandler.parse(result)
      self?.finishIfNotCancelled()
      self?.callback(self)
    }
  }
}

Then, the usage of the NetworkStatefulOperation class is quite straightforward:

// 1. Create an instance of `NetworkStatefulOperation` class:
let networkiOperation = NetworkStatefulOperation(service, parser) {
  // 3. As soon as the operation is finished, this closure will be executed with the operation state that can futher be handled to properly update the UI:
  updateUI(with: $0.state)
}
// 2. Then call the `start` method:
networkOperation.start()

Atomics

Guarantees safe mutation of a property in multiple async dispatch queues. Simply wrap a property in Atomic type:

let atomic = Atomic(0)

DispatchQueue.global().async {
  atomic.modify { $0 + 1 }
}

DispatchQueue.global().async {
  atomic.modify { $0 + 1 }
}

You can also use slightly more performance-friendly AtomicInt and AtomicBool classes, hence there is no dynamic dispatch involved (though Swift compiler is smart enough to apply complier optimization called compile-time generic specialization)

Locks

Read Write Lock

A syncronozation primitive that solves one of the readers–writers problems:

let rwLock = ReadWriteLock()

rwLock.writeLock()
sharedValue += 1
rwLock.unlock()

Or you can restrict the reading access, so other threads will not be able to read the mutated value of a property until the lock will be released:

let rwLock = ReadWriteLock()

rwLock.readLock()
sharedValue += 1
rwLock.unlock()

Unfair Lock

A lock which causes a thread trying to acquire it to simply wait in a loop ("spin"), while repeatedly checking if the lock is available:

let unfairLock = UnfairLock()

unfairLock.lock()
sharedValue += 1
unfairLock.unlock()

Mutex

Used to protect shared resources. A mutex is owned by the task that takes it. In a given region of code only one thread is active:

let mutex = Mutex()

mutex.withCriticalScope {
  return sharedValue += 1
}

Dispatch Queue

There is a convenience method that removes the need to pass .now() + time in order to make an async call:

DispatchQueue.main.asyncAfter(seconds: 2.5) {
  expectation.fulfill()
}

Also, DispatchQueue.once was returned back::

// The following concurrentQueue is called multiple times, though the caughtValue will be set to value only once.
concurrentQueue.async {
  DispatchQueue.once(token: "caught") {
    caughtValue = value
  }
}

🏗 Installation

Swift Package Manager

Xcode 11+

  1. Open MenuBarFileSwift PackagesAdd Package Dependency...
  2. Paste the package repository url https://github.com/jVirus/concurrency-kit and hit Next.
  3. Select the installment rules.

After specifying which version do you want to install, the package will be downloaded and attached to your project.

Package.swift

If you already have a Package.swift or you are building your own package simply add a new dependency:

dependencies: [
    .package(url: "https://github.com/jVirus/concurrency-kit", from: "1.0.0")
]

Manual

You can always use copy-paste the sources method 😄. Or you can compile the framework and include it with your project.

👨‍💻 Author

Astemir Eleev

🔖 Licence

The project is available under MIT licence

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].