Prototype actor and async/await toolkit for Swift 5.5+

Related tags

Utility desolate
Overview

Desolate

Prototype actor and async/await toolkit for Swift 5.5+

\"\(item)\"" case .store(item: let item, ref: _): return "POST: \"\(item)\"" case .add(item: let item): return "POST: \"\(item)\"" case .get(key: let key, ref: _): return "GET: \(key)" case .getAll(ref: _): return "GET: *" case .delete(key: let key): return "DELETE: \(key)" } } } actor Store: AbstractDesolate { public var status: Signal = .running private var storage: [String: (String, Date)] = [:] public func onMessage(msg: StoreEvent) async -> Signal { print("Received: \(msg)") switch msg { case .update(let key, let item): storage[key] = (item, Date()) case .store(let item, let ref): let key = UUID().uuidString storage[key] = (item, Date()) ref.tell(with: key) case .get(let key, let ref): ref.tell(with: storage[key]?.0) case .getAll(let ref): ref.tell(with: storage.values.sorted { $0.1 <= $1.1 } .map{ $0.0 }) case .delete(let key): storage.removeValue(forKey: key) } return .running } } let desolate = Desolate(of: Store()) desolate.tell(with: .add(item: "Hello")) // Passing message to Actor while maintaining actor-isolation ">
import Desolate

enum StoreEvent: CustomStringConvertible {
    case update(key: String, item: String)
    case store(item: String, ref: RecipientRef<String>)
    case add(item: String)
    case get(key: String, ref: RecipientRef<String?>)
    case getAll(ref: RecipientRef<[String]>)
    case delete(key: String)

    var description: String {
        switch self {
        case .update(key: let key, item: let item):
            return "PUT/PATCH: \(key) -> \"\(item)\""
        case .store(item: let item, ref: _):
            return "POST: \"\(item)\""
        case .add(item: let item):
            return "POST: \"\(item)\""    
        case .get(key: let key, ref: _):
            return "GET: \(key)"
        case .getAll(ref: _):
            return "GET: *"
        case .delete(key: let key):
            return "DELETE: \(key)"
        }
    }
}

actor Store: AbstractDesolate {
    public var status: Signal = .running

    private var storage: [String: (String, Date)] = [:]

    public func onMessage(msg: StoreEvent) async -> Signal {
        print("Received: \(msg)")

        switch msg {
        case .update(let key, let item):
            storage[key] = (item, Date())

        case .store(let item, let ref):
            let key = UUID().uuidString
            storage[key] = (item, Date())
            ref.tell(with: key)

        case .get(let key, let ref):
            ref.tell(with: storage[key]?.0)

        case .getAll(let ref):
            ref.tell(with: storage.values.sorted { $0.1 <= $1.1 } .map{ $0.0 })

        case .delete(let key):
            storage.removeValue(forKey: key)
        }

        return .running
    }
}

let desolate = Desolate(of: Store())

desolate.tell(with: .add(item: "Hello")) // Passing message to Actor while maintaining actor-isolation

Feedback

If you have any feedback, feel free to reach out through the issues tab or through my Twitter @d_exclaimation.

Comments
  • Reservoir

    Reservoir

    Data structure that handle multiple topic stream

    • Reservoir, Multiple topic, multiple source / upstream, multiple downstream, single type broadcast stream.
    • Confluence, Merge combine stream.
    • Cascade, Merge concat stream.

    Not sure whether the other two will come just yet or should be suspended to focus on optimizing current code

    enhancement 
    opened by d-exclaimation 1
  • Renamed Jet stream

    Renamed Jet stream

    Jet stream is a pretty unique name to call a reactive stream but it's not that descriptive. There are plenty of names that would fit better and explain the use of the data structures.

    enhancement 
    opened by d-exclaimation 1
  • Bug / Enhancement: Use Desolate built-in Signal status as suppose to using custom state

    Bug / Enhancement: Use Desolate built-in Signal status as suppose to using custom state

    Description

    For some reason, I didn't use the built-in Signal status on each Desolated actors and declare unnecessary additional boolean state that require management myself. I should opt in using Signal as much as possible as it works nicely automatically and does not require manual state management.

    Code mentioned

    • https://github.com/d-exclaimation/desolate/blob/190f0d4474ae93e19e60ebf533aecd89d2d6230c/Sources/Desolate/Streaming/Jet.swift#L24
    • https://github.com/d-exclaimation/desolate/blob/190f0d4474ae93e19e60ebf533aecd89d2d6230c/Sources/Desolate/Streaming/Jet.swift#L29
    • https://github.com/d-exclaimation/desolate/blob/190f0d4474ae93e19e60ebf533aecd89d2d6230c/Sources/Desolate/Streaming/Jet.swift#L37

    Solution

    • Removed NonStop from Jet and use the Signal
    // (removed) private var closed: Bool = false
    
    public var status: Signal = .running
    private var flows: [UUID: Flow] = [:]
    
    /// Interface for Desolate
    public func onMessage(msg: Act) async -> Signal {
        // (removed) guard !closed else { return same }
    
        switch msg {
        case .next(let message):
            for nozzle in flows.values {
                await nozzle.task(with: message)
            }
        case .complete:
            // (removed) closed = true
            for queue in flows.values {
                await queue.task(with: nil)
            }
            flows.removeAll()
            return .stopped
        case .attach(let id, let nozzle):
            flows[id] = nozzle
        case .detach(id: let id):
            flows.removeValue(forKey: id)
        }
        return .running
    }
    
    bug enhancement 
    opened by d-exclaimation 1
  • Removed usage on `fatalError` and unsafe mutability

    Removed usage on `fatalError` and unsafe mutability

    Descriptions

    Removed usage of any fatal error and unsafe mutations to prevent unsuspecting exceptions and behavior

    Code references

    Fatal Error

    • https://github.com/d-exclaimation/desolate/blob/1072648c8bf27fdd7608d0393f042ea9d50f6585/Sources/Desolate/Decorator/Extensions/Desolate%2BStateHook.swift#L20
    • https://github.com/d-exclaimation/desolate/blob/1072648c8bf27fdd7608d0393f042ea9d50f6585/Sources/Desolate/Decorator/Desolated.swift#L31
    • https://github.com/d-exclaimation/desolate/blob/ec0ca0510e332b6ca4c95b322d3ed6e7223fa570/Sources/Desolate/Delivery/Receiver.swift#L72

    Unsafe mutation

    • https://github.com/d-exclaimation/desolate/blob/ec0ca0510e332b6ca4c95b322d3ed6e7223fa570/Sources/Desolate/Delivery/Inbox.swift#L10
    enhancement 
    opened by d-exclaimation 1
  • Source and Reservoir

    Source and Reservoir

    Changelog

    • Renamed Jet to Source
    • Renamed internal actors accordingly (Nozzle.Current -> Nozzle.Sink, Jet.Pipeline -> Source.Supply)
    • Added Reservoir a multiple topic, single type pubsub for Source stream
    opened by d-exclaimation 0
  • Xcode 13.2 Update, Older Versions support, Improvement with Callbacks

    Xcode 13.2 Update, Older Versions support, Improvement with Callbacks

    • [ ] Updated restriction to be macOS v10.15
    • [x] Improvement with callbacks (1.4.0)
    • [x] Improvement with @Sendable and Sendable object for callbacks (1.4.0)
    • [x] Removal of unused code (1.4.0)
    • [x] Improvement in Source (1.4.0)
    • [ ] Improvement in Nozzle termination
    enhancement 
    opened by d-exclaimation 0
Releases(1.4.0)
  • 1.4.0(Dec 15, 2021)

  • 1.3.0(Dec 6, 2021)

    What's Changed

    • Source and Reservoir by @d-exclaimation in https://github.com/d-exclaimation/desolate/pull/7

    Full Changelog: https://github.com/d-exclaimation/desolate/compare/1.2.3...1.3.0

    Source code(tar.gz)
    Source code(zip)
  • 1.2.3(Dec 4, 2021)

  • 1.2.2(Nov 27, 2021)

  • 1.2.1(Nov 24, 2021)

  • 1.2.0(Nov 10, 2021)

    Description

    • Functional Desolate, Actors with just Functions
    • Pipe pattern for AsyncSequence streams
    • A more refined approach to AskPattern
    • TimeInterval to Nanosecond bridge

    Full Changelog: https://github.com/d-exclaimation/desolate/compare/1.1.2...1.2.0

    Source code(tar.gz)
    Source code(zip)
  • 1.1.2(Nov 5, 2021)

    Changelog

    • Updated Nozzle performance by removing static delay and replaced with re-enqueue to managed concurrency consistency.
    • Added capabilities to construct Nozzle with a builder closure,
    • Make Task, Optional, Result extensions public.

    Full Changelog: https://github.com/d-exclaimation/desolate/compare/1.1.1...1.1.2

    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Nov 5, 2021)

    Description

    First patch, make every stable API to be public allowing a proper complete experience

    Changelog

    • Make AskPattern properly public
    • Make @Desolated attribute public
    • Updated documentation
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Nov 4, 2021)

    Description

    Streaming update

    Changelog

    • Added Jet and Nozzle stream
    • Updated built-in actor implementation to use nested typing instead of top level ones
    • Improved documentation
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Nov 3, 2021)

    Description

    A functional toolkit for Swift Actors and Concurrency

    Changelog

    • Functional struct interface for Actors
    • Bridges functions for synchronous and asynchronous
    • Built-in Desolated actors like Capsules and Timers
    Source code(tar.gz)
    Source code(zip)
Owner
d-exclaimation
Software developer improving his craft
d-exclaimation
Backward compatible async/await for URLSession!

URLSessionBackport URLSessionBackport aims to make it possible to use URLSession's new async/await syntax on older OSs, namely iOS 13 or macOS 10.15 a

Mochi Development, Inc. 39 Sep 21, 2022
Async+ for Swift provides a simple chainable interface for your async and throwing code, similar to promises and futures

Async+ for Swift provides a simple chainable interface for your async and throwing code, similar to promises and futures. Have the best of both worlds

async_plus 132 Jan 6, 2023
NFC Tag Reader Prototype

Building an NFC Tag-Reader App Read NFC tags with NDEF messages in your app. Overview This sample code project shows how to use Core NFC in an app to

Pranav Kasetti 2 Jun 29, 2022
Readium Mobile is a toolkit for ebooks, audiobooks and comics written in Swift & Kotlin.

Readium Swift Toolkit Readium Mobile is a toolkit for ebooks, audiobooks and comics written in Swift & Kotlin. This toolkit is a modular project, whic

Readium 89 Dec 30, 2022
Ethereum Wallet Toolkit for iOS - You can implement an Ethereum wallet without a server and blockchain knowledge.

Introduction EtherWalletKit is an Ethereum Wallet Toolkit for iOS. I hope cryptocurrency and decentralized token economy become more widely adapted. H

Sung Woo Chang 136 Dec 25, 2022
Swift-DocC is a documentation compiler for Swift frameworks and packages aimed at making it easy to write and publish great developer documentation.

Swift-DocC is a documentation compiler for Swift frameworks and packages aimed at making it easy to write and publish great developer docum

Apple 833 Jan 3, 2023
BCSwiftTor - Opinionated pure Swift controller for Tor, including full support for Swift 5.5 and Swift Concurrency

BCSwiftTor Opinionated pure Swift controller for Tor, including full support for

Blockchain Commons, LLC — A “not-for-profit” benefit corporation 4 Oct 6, 2022
Zip - A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip.

Zip A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip. Usage Import Zip at the top of the Swift file

Roy Marmelstein 2.3k Jan 3, 2023
Useful Swift code samples, extensions, functionalities and scripts to cherry-pick and use in your projects

SwiftyPick ?? ?? Useful Swift code samples, extensions, functionalities and scripts to cherry-pick and use in your projects. Purpose The idea behind t

Manu Herrera 19 May 12, 2022
A handy collection of Swift method and Tools to build project faster and more efficient.

SwifterKnife is a collection of Swift extension method and some tools that often use in develop project, with them you might build project faster and

李阳 4 Dec 29, 2022
TypeStyle is a handy app for iPhone and iPad that generates text using different styles and decorations. It is a native Swift iOS app.

TypeStyle TypeStyle is a handy app for iPhone and iPad that generates text using different styles and decorations. It is a native Swift iOS app. Featu

Eugene Belinski 31 Dec 14, 2022
A lightweight extension to Swift's CollectionDifference, supporting moves in addition to removals and insertions, critical when updating interfaces and managing reference types.

DifferenceTracker is a lightweight extension to Swift's CollectionDifference. It defines moves in addition to removals and insertions, critical when updating interfaces and managing reference types.

Giles Hammond 2 Nov 25, 2022
Swift Markdown is a Swift package for parsing, building, editing, and analyzing Markdown documents.

Swift Markdown is a Swift package for parsing, building, editing, and analyzing Markdown documents.

Apple 2k Dec 28, 2022
Validate iOS, Android, and Mac localizations. Find errors in .strings, .stringsdict, and strings.xml files.

Locheck An Xcode and Android localization file validator. Make sure your .strings, .stringsdict, and strings.xml files do not have any errors! What do

Asana 73 Dec 13, 2022
Customize and resize sheets in SwiftUI with SheeKit. Utilise the power of `UISheetPresentationController` and other UIKit features.

SheeKit Customize and resize sheets in SwiftUI with SheeKit. Utilise the power of UISheetPresentationController and other UIKit features. Overview She

Eugene Dudnyk 67 Dec 31, 2022
Tools and helpers to make building apps faster and safer.

The UBFoundation framework provides a set of useful tools and helpers to make building apps faster and safer.

Ubique 7 Dec 19, 2022
Paul Hudson redesigned and remastered the original MoonshotApp. And so I followed the tutorial

Moonshot App for iOS. parsing some json files, using generics, and creating multi page app. Application provides simple informations from the Apollo m

Pavel Surový 0 Dec 7, 2021
Easy CBOR encoding and decoding for iOS, macOS, tvOS and watchOS.

CBORCoding CBORCoding is a lightweight framework containing a coder pair for encoding and decoding Codable conforming types to and from CBOR document

Joe Newton 23 Nov 8, 2022