• Stars
    star
    42
  • Rank 656,625 (Top 13 %)
  • Language
    Crystal
  • License
    MIT License
  • Created over 6 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Type aware promises for crystal lang

Crystal Lang Promises

CI

Provides a fully typed implementation of promises for crystal lang.

A word of advice

It's good practice to only expose synchronous APIs in crystal lang. If you are building a library that uses promises internally, make sure to call #get when returning on public interfaces.

Overview

A promise represents the eventual result of an operation. You can use a promise to specify what to do when an operation eventually succeeds or fails.

require "promise"

# A promise defines the eventual type that will be returned
promise = Promise.new(String)

# You can then perform some asynchronous action that will resolve the promise
channel.send {promise, arg1, arg2}

# A callback can be used to access the result.
# All return values are nilable
promise.then do |result|
  puts result
end

# You can also handle Exceptions.
# All failure responses are of type Exception
promise.catch do |error|
  puts error.message
end

# If you don't care about the result but want to be notified of job completion
promise.finally do |error|
  if error
    job_failed
  else
    job_success
  end
end

# You can also pause execution and wait for the value
# This will raise an error if the promise was rejected
begin
  result = promise.get
rescue error
  puts error.message
end

Simple concurrency control

Promise.defer is similar to spawn, however you can wait for it to complete with a value or error. The promise type is inferred from the return type of the defer block.

Promise.defer {
  # your concurrent code here, in spawned fiber
}.then { |result|
  # process returned value
}.catch { |error|
  # handle errors
}

Promise.all

The Promise.all(Enumerable) method returns a single Promise that resolves when all of the promises in the argument(s) have resolved or when the argument contains no promises. It rejects with the reason of the first promise that rejects.

# synchronous response

value1, value2 = Promise.all(
  Promise.defer { function1 },
  Promise.defer { function2 }
).get


# using callbacks

Promise.all(
  Promise.defer { function1 },
  Promise.defer { function2 }
).then do |results|
  results.each {  }
end

There are no restrictions placed on return types so function1 can return a String and function2 an Int32, for example.

Promise.race

The Promise.race(Enumerable) method returns a promise that resolves or rejects as soon as one of the promises resolves or rejects, with the value or reason from that promise. It will raise an error if no promises are provided.

Promise.race(
  Promise.defer { sleep rand(0.0..1.0); "p1 wins" },
  Promise.defer { sleep rand(0.0..1.0); "p2 wins" }
).get

Promise.map

Promise also support asynchronous maps over Enumerable types, yielding an array of the resolved elements.

Promise.map([1, 2, 3]) do |x|
  sleep x
  x
end.sum # => 6

Multiple receivers

There might be multiple parties interested in the results of an operation. Promises ensure all receivers receive the result when the operation is complete.

operation = Promise.defer {
  # your concurrent code here, in spawned fiber
}

operation.then do |result|
  puts "log the result #{result}"
end

operation.then do |result|
  email(result.contacts) if result.state == :not_good
end

Of course new receivers will probably be added dynamically at runtime

Promise chaining

Promises can be chained together and the return type of every .then block is used to build the next promise, so it is simple to transform values.

Promise.defer {
  # obtains the age of an imaginary person
  get_age
}.catch { |error|
  if error.message == "not born"
    # We can recover the operation by returning a compatible value
    0
  else
    raise error
  end
}.then { |age|
  # we can perform another async operation
  Promise.defer {
    print_birthday_card(age)
  }
}.then {
  log_success
}.catch { |error|
  log_error(error)
}.finally {
  print_next_card
}

More Repositories

1

spider-gazelle

A Rails esque web framework with a focus on speed and extensibility for crystal lang
Crystal
179
star
2

tasker

Scheduled tasks for crystal lang
Crystal
56
star
3

bindata

BinData - Parsing Binary Data in Crystal Lang
Crystal
48
star
4

ssh2.cr

libssh2 binding for Crystal language
Crystal
44
star
5

action-controller

A rails-esque controller framework for crystal lang
Crystal
41
star
6

active-model

A rails-esque model framework for crystal lang
Crystal
28
star
7

rethinkdb-orm

RethinkDB ORM for Crystal lang
Crystal
24
star
8

crystal-mqtt

Crystal lang implementation of the MQTT protocol, a lightweight protocol for publish/subscribe messaging
Crystal
20
star
9

ffmpeg

ffmpeg crystal bindings
Crystal
19
star
10

crystal-ldap

a Crystal lang LDAP client
Crystal
18
star
11

qr-code

a QR Code implementation written in crystal lang
Crystal
17
star
12

crystal-snmp

SNMP implementation for crystal lang
Crystal
16
star
13

json-schema

Describe crystal-lang JSON serializable types with JSON Schema
Crystal
13
star
14

priority-queue

Priority Queue and Heap implementation for Crystal Lang
Crystal
13
star
15

bisect

Library for maintaining sorted Arrays
Crystal
12
star
16

pars

Parser combinator library for crystal-lang
Crystal
11
star
17

pinger

Microlibrary to perform ping requests with Crystal Lang
Crystal
11
star
18

telnet.cr

Telnet protocol helper for crystal lang
Crystal
11
star
19

crystal-openai

OpenAI ChatGPT, GPT-3, GPT-4, DALLΒ·E, Whisper API Client for Crystal
Crystal
11
star
20

pg-orm

Postgres ORM for Crystal Lang
Crystal
10
star
21

inactive-support

Utilities for crystal-lang
Crystal
10
star
22

mdns

Crystal Lang mDNS and DNS-SD Support
Crystal
8
star
23

tensorflow_lite

tensorflow lite bindings for crystal lang
Crystal
8
star
24

ed25519

Ed25519 high-performance public-key signature system for crystal lang
Crystal
7
star
25

secure-remote-password

Crystal implementation of the Secure Remote Password protocol (SRP-6a)
Crystal
7
star
26

crystal-gpt

ChatGPT plugin template that allows you to focus on writing actions, automatically generating the required metadata
Crystal
7
star
27

connect-proxy

crystal lang connect / HTTP proxy implementation
Crystal
7
star
28

simple_retry

a tool for retrying code blocks
Crystal
6
star
29

crunits

Physical quantity and units of measure conversion and math for crystal lang
Crystal
6
star
30

secrets-env

Extension to the crystal lang ENV module to support reading secrets
Crystal
6
star
31

v4l2.cr

crystal lang video for linux device helpers / bindings
Crystal
5
star
32

log_helper

Extension for Crystal Log to aid logging key-value data
Crystal
5
star
33

cmac

Crystal implementation of the Cipher-based Message Authentication Code (CMAC)
Crystal
5
star
34

readers-writer

A simple readers writer lock for crystal lang
Crystal
5
star
35

worker_pool

a basic fiber pool implementation for crystal lang
Crystal
5
star
36

matter

A complete Crystal implementation of the Matter protocol specification (https://buildwithmatter.com). Includes full support for controller, device, commissioning, secure communications, device types, and cluster definitions.
Crystal
5
star
37

guide

Spider Gazelle Documentation
Python
4
star
38

ntlm

NTLM authentication for crystal lang
Crystal
4
star
39

digest-auth

HTTP digest auth for crystal lang
Crystal
4
star
40

eventbus

Listen for Postgres database change events and publish them to event listeners
Crystal
3
star
41

knx

KNX protocol support for crystal lang
Crystal
3
star
42

tokenizer

Simplified binary stream tokenization for crystal lang
Crystal
2
star
43

crystal-dtls

DTLS support for crystal lang
Crystal
2
star
44

stumpy_resize

resizes stumpy canvas images in pure crystal
Crystal
2
star
45

upload-signer

Provide API for generating pre-signed URLs for file uploads to cloud storage
Crystal
2
star
46

SPAKE2_plus

a crystal lang implementation of SPAKE2+, a Password Authenticated Key Exchange (PAKE) protocol
Crystal
2
star
47

stomp

crystal lang implementation of the STOMP protocol
Crystal
1
star
48

tlv

Matter TLV encoder/decoder
Crystal
1
star
49

gpio.cr

crystal lang bindings for linux gpiod
Crystal
1
star
50

HKDF

HMAC-based Extract-and-Expand Key Derivation Function (HKDF) for crystal lang
Crystal
1
star
51

panopticon

Distributed tracing for services built in crystal-lang
Crystal
1
star
52

tflite_image

image classification and feature detection with tflite and crystal lang
Crystal
1
star
53

tflite_pipeline

video processing AI pipeline leveraging tflite_image
Crystal
1
star
54

link-header

Crystal Lang HTTP Link Header Parser
Crystal
1
star