Additional Durable Functions implementation.

This commit continues the Durable Functions implementation:

* Changes `azure-functions-durable` crate to use the released version of the
`hyper` crate, but with the 0.1.0 futures-compatibility layer.  This fixes the
issue where the reactor could not be found for the client with a 0.1.0
futures-based tokio reactor that is being used by the Azure Functions for Rust
runtime.

* Implement the `DurableOrchestrationClient` binding to wrap an
`OrchestrationClient` and provide the `start_new` method.  More methods will be
implemented later.

* Implement the `DurableActivityContext` binding to extract the instance
identifier and input from the binding data.

* Implemented a mechanism for outer orchestration futures to control inner
futures for updating the current orchestration event, which should occur
immediately after the future is ready.

* Implemented proper replay detection.

* Implemented the `join_all` method on `DurableOrchestrationContext`.

* Implemented the Durable Functions example (still needs documentation).

* Various clippy and code clean up fixes.
This commit is contained in:
Peter Huene 2019-07-25 16:52:04 -07:00 committed by Peter Huene
parent e1dd374796
commit 60b5678248
No known key found for this signature in database
GPG Key ID: E1D265D820213D6A
19 changed files with 900 additions and 450 deletions

388
Cargo.lock generated
View File

@ -21,26 +21,18 @@ name = "approx"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -48,6 +40,7 @@ name = "azure-functions"
version = "0.10.0"
dependencies = [
"azure-functions-codegen 0.10.0",
"azure-functions-durable 0.10.0",
"azure-functions-shared 0.10.0",
"backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -62,8 +55,8 @@ dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -85,6 +78,24 @@ dependencies = [
"syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "azure-functions-durable"
version = "0.10.0"
dependencies = [
"chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_builder 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mockito 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "azure-functions-sdk"
version = "0.10.0"
@ -112,7 +123,6 @@ dependencies = [
"prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-grpc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -135,7 +145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -144,8 +154,8 @@ name = "backtrace-sys"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -210,16 +220,15 @@ dependencies = [
[[package]]
name = "c2-chacha"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
version = "1.0.46"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -242,7 +251,7 @@ name = "chrono"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
@ -276,7 +285,7 @@ name = "codegen"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -299,23 +308,23 @@ dependencies = [
[[package]]
name = "crossbeam-deque"
version = "0.7.1"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-epoch"
version = "0.7.2"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -336,6 +345,16 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ctrlc"
version = "3.1.3"
@ -345,6 +364,66 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "darling"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "darling_core"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "darling_macro"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "derive_builder"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_builder_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "derive_builder_core"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "digest"
version = "0.8.1"
@ -360,6 +439,7 @@ dependencies = [
"azure-functions 0.10.0",
"futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -455,7 +535,7 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -465,7 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -525,11 +605,11 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.1.12"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -543,7 +623,7 @@ dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -578,7 +658,15 @@ name = "heck"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hermit-abi"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -657,21 +745,39 @@ dependencies = [
]
[[package]]
name = "indexmap"
version = "1.2.0"
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "idna"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "indexmap"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itertools"
version = "0.8.0"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -698,7 +804,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.64"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -727,6 +833,11 @@ name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "2.2.1"
@ -734,7 +845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memoffset"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -749,7 +860,7 @@ dependencies = [
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@ -763,7 +874,7 @@ version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -778,6 +889,22 @@ dependencies = [
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mockito"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "multimap"
version = "0.4.0"
@ -789,7 +916,7 @@ version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -799,23 +926,18 @@ version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-integer"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -832,15 +954,16 @@ name = "num-traits"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num_cpus"
version = "1.10.1"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -865,10 +988,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -931,7 +1054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ppv-lite86"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -967,7 +1090,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
@ -983,7 +1106,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1033,7 +1156,7 @@ version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1044,8 +1167,8 @@ name = "rand"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1056,7 +1179,7 @@ name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1078,7 +1201,7 @@ name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1157,6 +1280,11 @@ dependencies = [
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "scoped-tls"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scopeguard"
version = "1.0.0"
@ -1210,6 +1338,16 @@ dependencies = [
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_repr"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "service-bus-example"
version = "0.1.0"
@ -1235,7 +1373,6 @@ version = "0.1.0"
dependencies = [
"azure-functions 0.10.0",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1246,8 +1383,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "0.6.10"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "string"
@ -1257,6 +1397,11 @@ dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "strsim"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.8.0"
@ -1306,7 +1451,7 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1334,7 +1479,7 @@ name = "time"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1355,7 +1500,7 @@ dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1390,6 +1535,24 @@ dependencies = [
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-core"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-current-thread"
version = "0.1.6"
@ -1438,7 +1601,7 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1473,13 +1636,13 @@ name = "tokio-threadpool"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1517,7 +1680,7 @@ dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1646,9 +1809,25 @@ name = "ucd-trie"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-segmentation"
version = "1.3.0"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -1666,6 +1845,16 @@ name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vec_map"
version = "0.8.1"
@ -1707,7 +1896,7 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1776,9 +1965,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
@ -1788,8 +1976,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
"checksum cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "0213d356d3c4ea2c18c40b037c3be23cd639825c18f25ee670ac7813beeef99c"
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
"checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68"
@ -1797,11 +1985,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum codegen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bf02acd61125952ee148207cd411f9b73c9e218eab4b901375a82e1a443b6238"
"checksum colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cdb90b60f2927f8d76139c72dbde7e10c3a2bc47c8594c9c7a66529f2687c03"
"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
"checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f"
"checksum darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6"
"checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c"
"checksum darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1"
"checksum derive_builder 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ac53fa6a3cda160df823a9346442525dcaf1e171999a1cf23e67067e4fd64d4"
"checksum derive_builder_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0288a23da9333c246bb18c143426074a6ae96747995c5819d2947b64cd942b37"
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
@ -1822,40 +2017,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "86f148ef6b69f75bb610d4f9a2336d4fc88c4b5b67129d1a340dd0fd362efeec"
"checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571"
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
"checksum handlebars 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "91ef1ac30f2eaaa2b835fce73c57091cb6b9fc62b7eef285efbf980b0f20001b"
"checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
"checksum http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e06e336150b178206af098a055e3621e8336027e2b4d126bda0bc64824baaf"
"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
"checksum http-connection 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f6080cea47f7371d4da9a46dd52787c598ce93886393e400bc178f9039bac27"
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
"checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6"
"checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3"
"checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87fa75c9dea7b07be3138c49abbb83fd4bea199b5cdc76f9804458edc5da0d6e"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c"
"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
"checksum memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a85c1a8c329f11437034d7313dca647c79096523533a1c79e86f1d0f657c7cc"
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum mockito 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d910005896c16bb589e560173d10a7d5a4e747ea6f0c734ddcd9ad91b45e976"
"checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
"checksum num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "155394f924cdddf08149da25bfb932d226b4a593ca7468b08191ff6335941af5"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
@ -1866,7 +2065,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum pest_meta 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df43fd99896fd72c485fe47542c7b500e4ac1e8700bf995544d1317a60ded547"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23"
@ -1893,16 +2092,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0"
"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8"
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
"checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7bedb3320d0f3035594b0b723c8a28d7d336a3eda3881db79e61d676fb644c"
@ -1914,6 +2116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
"checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f"
"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71"
"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac"
"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af"
@ -1936,10 +2139,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "09c8070a9942f5e7cfccd93f490fdebd230ee3c3c9f107cb25bad5351ef671cf"
"checksum unicode-segmentation 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49f5526225fd8b77342d5986ab5f6055552e9c0776193b5b63fd53b46debfad7"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"

View File

@ -78,7 +78,7 @@ fn validate_orchestration_function(func: &ItemFn) {
);
}
if let ReturnType::Type(_, ty) = &func.sig.decl.output {
if let ReturnType::Type(_, ty) = &func.sig.output {
match ty.as_ref() {
Type::Path(tp) => {
if last_segment_in_path(&tp.path).ident != ORCHESTRATION_OUTPUT_TYPE {
@ -135,7 +135,7 @@ fn validate_activity_function(func: &ItemFn) {
}
}
if let ReturnType::Type(_, ty) = &func.decl.output {
if let ReturnType::Type(_, ty) = &func.sig.output {
validate_return_binding(&*ty);
}
}

View File

@ -9,8 +9,8 @@ homepage = "https://functions.rs"
edition = "2018"
[dependencies]
futures-preview = { version = "0.3.0-alpha.17" }
hyper = { git = "https://github.com/hyperium/hyper", rev = "1d00bb29d4f5d123ddd04d7f78de3b1a98fe7dfb", features=["runtime"] }
futures-preview = { version = "0.3.0-alpha.17", features = ["compat"] }
hyper = "0.12.33"
serde = { version="1.0.97", features = ["derive"] }
serde_json = "1.0.40"
tokio = "0.1.22"

View File

@ -2,38 +2,20 @@
#![feature(async_await)]
#![feature(result_map_or_else)]
#[macro_use]
extern crate derive_builder;
extern crate hyper;
//extern crate hyper_tls;
extern crate futures;
use crate::futures::FutureExt;
use crate::futures::TryFutureExt;
use crate::futures::TryStreamExt;
use chrono::prelude::*;
use futures::{future, Future};
use log::{debug, info, warn};
use serde::{Deserialize, Serialize};
use serde_json::{from_slice, from_str, Map, Value};
use std::fmt::{Debug, Display, Formatter};
use derive_builder::Builder;
use futures::{
compat::{Future01CompatExt, Stream01CompatExt},
TryStreamExt,
};
use hyper::{client::HttpConnector, Body, Client, Request, StatusCode};
use log::debug;
use serde::Deserialize;
use serde_json::{from_slice, to_string, Map, Value};
use std::fmt::{Display, Formatter};
use std::result::Result::*;
use url::Url;
//use hyper_tls::HttpsConnector;
use hyper::{client::HttpConnector, Body, Client, Request, StatusCode, Uri};
static EVENT_NAME_PLACEHOLDER: &'static str = "{eventName}";
static FUNC_NAME_PLACEHOLDER: &'static str = "{functionName}";
static INSTANCE_ID_PLACEHOLDER: &'static str = "[/{instanceId}]";
static REASON_PLACEHOLDER: &'static str = "{text}";
static CREATED_TIME_FROM_KEY: &'static str = "createdTimeFrom";
static CREATED_TIME_TO_KEY: &'static str = "createdTimeTo";
static RUNTIME_STATUS_KEY: &'static str = "runtimeStatus";
static SHOW_HISTORY_KEY: &'static str = "showHistory";
static SHOW_HISTORY_OUTPUT_KEY: &'static str = "showHistoryOutput";
static SHOW_INPUT_KEY: &'static str = "showInput";
#[derive(Debug, Clone, Builder)]
pub(crate) struct OrchestrationEndpoint {
base_uri: Url,
@ -197,12 +179,10 @@ pub enum OrchestrationRuntimeStatus {
impl Display for OrchestrationRuntimeStatus {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
// or, alternatively:
// fmt::Debug::fmt(self, f)
}
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub enum OrchestrationClientError {
//400
InstanceFailedOrTerminated,
@ -218,6 +198,32 @@ pub enum OrchestrationClientError {
InvalidResponse,
}
impl Display for OrchestrationClientError {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
match self {
OrchestrationClientError::InstanceFailedOrTerminated => {
write!(f, "instance failed or terminated")
}
OrchestrationClientError::InstanceCompletedOrFailed => {
write!(f, "instance completed or failed")
}
OrchestrationClientError::InstanceNotFound => write!(f, "instance not found"),
OrchestrationClientError::BadRaiseEventContent => write!(f, "bad raise event content"),
OrchestrationClientError::UnspecifiedError => write!(f, "unspecified error"),
OrchestrationClientError::CommunicationError(msg) => {
write!(f, "communication error: {}", msg)
}
OrchestrationClientError::InvalidResponse => write!(f, "invalid response"),
}
}
}
impl std::error::Error for OrchestrationClientError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct OrchestrationHistoryEvent {
@ -272,7 +278,7 @@ pub struct PurgeHistoryResult {
instances_deleted: u32,
}
type OrchestrationResult<T> = Result<T, OrchestrationClientError>;
pub type OrchestrationResult<T> = Result<T, OrchestrationClientError>;
pub struct OrchestrationClient {
endpoint: OrchestrationEndpoint,
@ -311,7 +317,7 @@ impl OrchestrationClient {
],
)
.unwrap();
let client_builder = client_builder.unwrap_or(Client::builder());
let client_builder = client_builder.unwrap_or_else(Client::builder);
OrchestrationClient {
endpoint: OrchestrationEndpoint::new_from_url(end_url),
client: client_builder.build_http(),
@ -354,7 +360,7 @@ impl OrchestrationClient {
.body(Body::empty())
.unwrap();
let res = self.client.request(req).await;
let res = self.client.request(req).compat().await;
match res {
Ok(response) => match response.status() {
StatusCode::OK
@ -362,7 +368,7 @@ impl OrchestrationClient {
| StatusCode::BAD_REQUEST
| StatusCode::NOT_FOUND
| StatusCode::INTERNAL_SERVER_ERROR => {
let body = response.into_body().try_concat().await;
let body = response.into_body().compat().try_concat().await;
body.map_or_else(
|e| {
Err(OrchestrationClientError::CommunicationError(format!(
@ -371,7 +377,7 @@ impl OrchestrationClient {
)))
},
|b| {
serde_json::from_slice::<OrchestrationStatus>(&b).map_err(|e2| {
from_slice::<OrchestrationStatus>(&b).map_err(|e2| {
OrchestrationClientError::CommunicationError(format!("{:?}", e2))
})
},
@ -436,7 +442,7 @@ impl OrchestrationClient {
.body(Body::empty())
.unwrap();
let res = self.client.request(req).await;
let res = self.client.request(req).compat().await;
match res {
Ok(response) => {
if response.status() > StatusCode::ACCEPTED {
@ -445,7 +451,7 @@ impl OrchestrationClient {
response.status()
)))
} else {
let body = response.into_body().try_concat().await;
let body = response.into_body().compat().try_concat().await;
body.map_or_else(
|e| {
Err(OrchestrationClientError::CommunicationError(format!(
@ -454,7 +460,7 @@ impl OrchestrationClient {
)))
},
|b| {
serde_json::from_slice(&b).map_err(|e2| {
from_slice(&b).map_err(|e2| {
OrchestrationClientError::CommunicationError(format!("{:?}", e2))
})
},
@ -488,11 +494,11 @@ impl OrchestrationClient {
.body(Body::empty())
.unwrap();
let res = self.client.request(req).await;
let res = self.client.request(req).compat().await;
match res {
Ok(response) => match response.status() {
StatusCode::OK => {
let body = response.into_body().try_concat().await;
let body = response.into_body().compat().try_concat().await;
body.map_or_else(
|e| {
Err(OrchestrationClientError::CommunicationError(format!(
@ -501,7 +507,7 @@ impl OrchestrationClient {
)))
},
|b| {
serde_json::from_slice(&b).map_err(|e2| {
from_slice(&b).map_err(|e2| {
OrchestrationClientError::CommunicationError(format!("{:?}", e2))
})
},
@ -556,11 +562,11 @@ impl OrchestrationClient {
.body(Body::empty())
.unwrap();
let res = self.client.request(req).await;
let res = self.client.request(req).compat().await;
match res {
Ok(response) => match response.status() {
StatusCode::OK => {
let body = response.into_body().try_concat().await;
let body = response.into_body().compat().try_concat().await;
body.map_or_else(
|e| {
Err(OrchestrationClientError::CommunicationError(format!(
@ -569,7 +575,7 @@ impl OrchestrationClient {
)))
},
|b| {
serde_json::from_slice(&b).map_err(|e2| {
from_slice(&b).map_err(|e2| {
OrchestrationClientError::CommunicationError(format!("{:?}", e2))
})
},
@ -597,7 +603,7 @@ impl OrchestrationClient {
query: InstanceQuery<'a>,
) -> OrchestrationResult<()>
where
D: Into<serde_json::Value>,
D: Into<Value>,
{
let raise_url = self.endpoint.raise_event_url(
query.instance_id.unwrap(),
@ -613,12 +619,10 @@ impl OrchestrationClient {
.method("POST")
.uri(raise_url.into_string())
.header("Content-Type", "application/json")
.body(Body::from(
serde_json::to_string(&event_data.into()).unwrap(),
))
.body(Body::from(to_string(&event_data.into()).unwrap()))
.unwrap();
let res = self.client.request(req).await;
let res = self.client.request(req).compat().await;
match res {
Ok(response) => match response.status() {
StatusCode::ACCEPTED => Ok(()),
@ -659,7 +663,7 @@ impl OrchestrationClient {
.body(Body::empty())
.unwrap();
let res = self.client.request(req).await;
let res = self.client.request(req).compat().await;
match res {
Ok(response) => match response.status() {
StatusCode::ACCEPTED => Ok(()),
@ -681,30 +685,29 @@ impl OrchestrationClient {
&self,
orchestrator_function_name: &str,
instance_id: Option<&str>,
input: Option<D>,
input: D,
) -> OrchestrationResult<String>
where
D: Into<serde_json::Value>,
D: Into<Value>,
{
let creationUri = self
let creation_uri = self
.endpoint
.create_new_instance_url(orchestrator_function_name, instance_id);
let body_value = input.map_or("".to_owned(), |i| i.into().to_string());
let req = Request::builder()
.method("POST")
.uri(creationUri.into_string())
.uri(creation_uri.into_string())
.header("Content-Type", "application/json")
.body(Body::from(body_value))
.body(Body::from(input.into().to_string()))
.unwrap();
let res = self.client.request(req).await;
let res = self.client.request(req).compat().await;
match res {
Ok(response) => {
if response.status() > StatusCode::ACCEPTED {
Err(OrchestrationClientError::UnspecifiedError)
} else {
let body = response.into_body().try_concat().await;
let body = response.into_body().compat().try_concat().await;
body.map_or_else(
|e| {
Err(OrchestrationClientError::CommunicationError(format!(
@ -769,7 +772,7 @@ impl OrchestrationClient {
.body(Body::empty())
.unwrap();
let res = self.client.request(req).await;
let res = self.client.request(req).compat().await;
match res {
Ok(response) => match response.status() {
StatusCode::ACCEPTED | StatusCode::GONE => Ok(()),
@ -787,23 +790,16 @@ impl OrchestrationClient {
}
}
#[cfg(test)]
use mockito;
use std::ops::Deref;
#[cfg(test)]
extern crate tokio;
#[cfg(test)]
mod tests {
use futures::future::lazy;
use mockito::mock;
use tokio;
use tokio_core::reactor::Core;
use super::*;
use futures::future::lazy;
use hyper::rt;
use hyper::{Body, Request, Response, Server};
use mockito::mock;
use serde_json::from_str;
use tokio;
use tokio_core::reactor::Core;
static EP_GOOD: &'static str = "http://localhost:7071/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=myHub&connection=Storage&code=myCode";
static EP_BAD: &'static str =
@ -816,7 +812,6 @@ mod tests {
let rewind_result = "http://localhost:7071/runtime/webhooks/durabletask/instances/1234/rewind?taskHub=myHub&connection=Storage&code=myCode&reason=myReason";
let rewind_url = endpoint.rewind_url("1234", "myReason", None, None, None);
println!("{:?}", rewind_url);
assert_eq!(rewind_url.to_string(), rewind_result);
}
@ -836,7 +831,7 @@ mod tests {
let compare_dt = Utc.ymd(2018, 2, 28).and_hms(5, 18, 49);
let h1_obj: OrchestrationHistoryEvent = serde_json::from_str(&h1).unwrap();
let h1_obj: OrchestrationHistoryEvent = from_str(&h1).unwrap();
assert_eq!(h1_obj.event_type, "ExecutionStarted");
assert_eq!(h1_obj.timestamp, compare_dt);
@ -852,7 +847,7 @@ mod tests {
}"#
.to_owned();
let h2_obj: OrchestrationHistoryEvent = serde_json::from_str(&h2).unwrap();
let h2_obj: OrchestrationHistoryEvent = from_str(&h2).unwrap();
assert_eq!(h2_obj.orchestration_status.is_some(), true);
assert_eq!(
h2_obj.orchestration_status.unwrap(),
@ -914,7 +909,7 @@ mod tests {
}"#
.to_owned();
let instance_status: OrchestrationStatus = serde_json::from_str(&example).unwrap();
let instance_status: OrchestrationStatus = from_str(&example).unwrap();
assert_eq!(instance_status.history_events.is_some(), true);
assert_eq!(instance_status.history_events.unwrap().len(), 5);

View File

@ -11,6 +11,7 @@ edition = "2018"
[dependencies]
azure-functions-shared = { version = "0.10.0", path = "../azure-functions-shared" }
azure-functions-codegen = { version = "0.10.0", path = "../azure-functions-codegen" }
azure-functions-durable = { version = "0.10.0", path = "../azure-functions-durable" }
http = "0.1"
tower-hyper = "0.1.1"
tower-grpc = "0.1.1"
@ -19,7 +20,7 @@ tower-util = "0.1.0"
tower-request-modifier = "0.1.0"
log = { version = "0.4.8", features = ["std"] }
futures01 = { package = "futures", version = "0.1.28" }
futures-preview = { version = "0.3.0-alpha.19", features = ["compat"], optional = true }
futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] }
clap = "2.33.0"
tokio = "0.1.22"
tokio-threadpool = "0.1.16"
@ -36,7 +37,7 @@ fs_extra = "1.1.0"
semver = "0.9.0"
[features]
unstable = ["azure-functions-codegen/unstable", "azure-functions-shared/unstable", "futures-preview"]
unstable = ["azure-functions-codegen/unstable", "azure-functions-shared/unstable"]
[dev-dependencies]
matches = "0.1.8"

View File

@ -1,7 +1,10 @@
use crate::rpc::TypedData;
use crate::rpc::{typed_data::Data, TypedData};
use serde::Deserialize;
use serde_json::{from_str, Number, Value};
use std::collections::HashMap;
const INSTANCE_ID_KEY: &str = "instanceId";
/// Represents the Durable Functions activity context binding.
///
/// The following binding attributes are supported:
@ -16,14 +19,32 @@ use std::collections::HashMap;
/// TODO: IMPLEMENT
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DurableActivityContext {}
pub struct DurableActivityContext {
/// The input to the activity function.
pub input: Value,
/// The orchestration instance identifier.
pub instance_id: String,
}
impl DurableActivityContext {
#[doc(hidden)]
pub fn new(data: TypedData, metadata: HashMap<String, TypedData>) -> Self {
println!("{:#?}", data);
println!("{:#?}", metadata);
DurableActivityContext {}
pub fn new(data: TypedData, mut metadata: HashMap<String, TypedData>) -> Self {
DurableActivityContext {
input: match data.data {
Some(Data::String(s)) => Value::String(s),
Some(Data::Json(s)) => from_str(&s).unwrap_or(Value::Null),
Some(Data::Int(i)) => Value::Number(i.into()),
Some(Data::Double(d)) => Value::Number(Number::from_f64(d).unwrap()),
_ => Value::Null,
},
instance_id: metadata
.remove(INSTANCE_ID_KEY)
.map(|data| match data.data {
Some(Data::String(s)) => s,
_ => panic!("expected a string for instance id"),
})
.expect("expected an instance id"),
}
}
}
@ -35,11 +56,19 @@ mod tests {
#[test]
fn it_constructs() {
let data = TypedData {
data: Some(Data::String(r#"{ }"#.to_owned())),
data: Some(Data::String("bar".to_string())),
};
let _ = DurableActivityContext::new(data, HashMap::new());
let mut metadata = HashMap::new();
metadata.insert(
INSTANCE_ID_KEY.to_string(),
TypedData {
data: Some(Data::String("foo".to_string())),
},
);
// TODO: implement
let context = DurableActivityContext::new(data, metadata);
assert_eq!(context.instance_id, "foo");
assert_eq!(context.input, Value::String("bar".to_string()));
}
}

View File

@ -1,9 +1,41 @@
use crate::{
durable::{CreationUrls, ManagementUrls},
rpc::{typed_data::Data, TypedData},
};
use crate::rpc::{typed_data::Data, TypedData};
use azure_functions_durable::{OrchestrationClient, OrchestrationResult};
use serde::Deserialize;
use serde_json::from_str;
use serde_json::{from_str, Value};
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct CreationUrls {
#[serde(rename = "createNewInstancePostUri")]
create_new_instance_url: String,
#[serde(rename = "createAndWaitOnNewInstancePostUri")]
create_new_instance_and_wait_url: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ManagementUrls {
id: String,
#[serde(rename = "statusQueryGetUri")]
status_query_url: String,
#[serde(rename = "sendEventPostUri")]
raise_event_url: String,
#[serde(rename = "terminatePostUri")]
terminate_url: String,
#[serde(rename = "rewindPostUri")]
rewind_url: String,
#[serde(rename = "purgeHistoryDeleteUri")]
purge_history_url: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct BindingData {
#[serde(rename = "taskHubName")]
task_hub: String,
creation_urls: CreationUrls,
management_urls: ManagementUrls,
}
/// Represents the Durable Functions orchestration client input binding.
///
@ -18,23 +50,41 @@ use serde_json::from_str;
/// # Examples
///
/// TODO: IMPLEMENT
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DurableOrchestrationClient {
#[serde(rename = "taskHubName")]
task_hub: String,
creation_urls: CreationUrls,
management_urls: ManagementUrls,
client: OrchestrationClient,
}
impl DurableOrchestrationClient {
/// Starts a new orchestration.
///
/// TODO: provide example
pub async fn start_new<D>(
&self,
orchestrator_function_name: &str,
instance_id: Option<&str>,
input: D,
) -> OrchestrationResult<String>
where
D: Into<Value>,
{
self.client
.start_new(orchestrator_function_name, instance_id, input)
.await
}
}
#[doc(hidden)]
impl From<TypedData> for DurableOrchestrationClient {
fn from(data: TypedData) -> Self {
match &data.data {
let data: BindingData = match &data.data {
Some(Data::String(s)) => {
from_str(s).expect("failed to parse durable orchestration client data")
}
_ => panic!("expected string data for durable orchestration client"),
};
DurableOrchestrationClient {
client: OrchestrationClient::new(&data.management_urls.status_query_url),
}
}
}
@ -46,39 +96,10 @@ mod tests {
#[test]
fn it_converts_from_typed_data() {
let data = TypedData {
data: Some(Data::String(r#"{"taskHubName":"test","creationUrls":{"createNewInstancePostUri":"http://localhost:8080/runtime/webhooks/durabletask/orchestrators/{functionName}[/{instanceId}]?code=foo","createAndWaitOnNewInstancePostUri":"http://localhost:8080/runtime/webhooks/durabletask/orchestrators/{functionName}[/{instanceId}]?timeout={timeoutInSeconds}&pollingInterval={intervalInSeconds}&code=foo"},"managementUrls":{"id":"INSTANCEID","statusQueryGetUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=DurableFunctionsHub&connection=Storage&code=foo","sendEventPostUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/raiseEvent/{eventName}?taskHub=DurableFunctionsHub&connection=Storage&code=foo","terminatePostUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/terminate?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=foo","rewindPostUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/rewind?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=foo","purgeHistoryDeleteUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=DurableFunctionsHub&connection=Storage&code=foo"}}"#.to_owned())),
data: Some(Data::String(r#"{"taskHubName":"DurableFunctionsHub","creationUrls":{"createNewInstancePostUri":"http://localhost:8080/runtime/webhooks/durabletask/orchestrators/{functionName}[/{instanceId}]?code=foo","createAndWaitOnNewInstancePostUri":"http://localhost:8080/runtime/webhooks/durabletask/orchestrators/{functionName}[/{instanceId}]?timeout={timeoutInSeconds}&pollingInterval={intervalInSeconds}&code=foo"},"managementUrls":{"id":"INSTANCEID","statusQueryGetUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=DurableFunctionsHub&connection=Storage&code=foo","sendEventPostUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/raiseEvent/{eventName}?taskHub=DurableFunctionsHub&connection=Storage&code=foo","terminatePostUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/terminate?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=foo","rewindPostUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/rewind?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=foo","purgeHistoryDeleteUri":"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=DurableFunctionsHub&connection=Storage&code=foo"}}"#.to_owned())),
};
let client: DurableOrchestrationClient = data.into();
assert_eq!(client.task_hub, "test");
assert_eq!(
client.creation_urls.create_new_instance_url,
"http://localhost:8080/runtime/webhooks/durabletask/orchestrators/{functionName}[/{instanceId}]?code=foo"
);
assert_eq!(
client.creation_urls.create_new_instance_and_wait_url,
"http://localhost:8080/runtime/webhooks/durabletask/orchestrators/{functionName}[/{instanceId}]?timeout={timeoutInSeconds}&pollingInterval={intervalInSeconds}&code=foo"
);
assert_eq!(client.management_urls.id, "INSTANCEID");
assert_eq!(
client.management_urls.status_query_url,
"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=DurableFunctionsHub&connection=Storage&code=foo"
);
assert_eq!(
client.management_urls.raise_event_url,
"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/raiseEvent/{eventName}?taskHub=DurableFunctionsHub&connection=Storage&code=foo"
);
assert_eq!(
client.management_urls.terminate_url,
"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/terminate?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=foo"
);
assert_eq!(
client.management_urls.rewind_url,
"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID/rewind?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=foo"
);
assert_eq!(
client.management_urls.purge_history_url,
"http://localhost:8080/runtime/webhooks/durabletask/instances/INSTANCEID?taskHub=DurableFunctionsHub&connection=Storage&code=foo"
);
assert_eq!(client.client.task_hub(), "DurableFunctionsHub");
}
}

View File

@ -1,16 +1,204 @@
use serde::Deserialize;
use serde_json::{from_str, Value};
use std::{cell::RefCell, collections::HashMap, rc::Rc};
use crate::durable::{Action, EventType, HistoryEvent};
use crate::{
durable::ExecutionResult,
rpc::{typed_data::Data, TypedData},
};
use chrono::{DateTime, Utc};
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use futures::future::join_all;
use serde::Deserialize;
use serde_json::{from_str, Value};
use std::{
cell::RefCell,
collections::HashMap,
future::Future,
pin::Pin,
rc::Rc,
task::{Context, Poll},
};
/// Represents a Future returned by the orchestration context.
pub trait OrchestrationFuture: Future {
#[doc(hidden)]
fn notify_inner(&mut self);
}
struct ActionFuture<T> {
result: Option<T>,
state: Rc<RefCell<OrchestrationState>>,
is_inner: bool,
}
impl<T> ActionFuture<T> {
fn new(result: Option<T>, state: Rc<RefCell<OrchestrationState>>) -> Self {
ActionFuture {
result,
state,
is_inner: false,
}
}
}
impl<T> Future for ActionFuture<T>
where
T: Unpin,
{
type Output = T;
fn poll(self: Pin<&mut Self>, _context: &mut Context) -> Poll<T> {
let this = self.get_mut();
if let Some(v) = this.result.take() {
if !this.is_inner {
this.state.borrow_mut().update();
}
return Poll::Ready(v);
}
Poll::Pending
}
}
impl<T> OrchestrationFuture for ActionFuture<T>
where
T: Unpin,
{
fn notify_inner(&mut self) {
self.is_inner = true;
}
}
/// Future for the `DurableOrchestrationContext::join_all` function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct JoinAll<F>
where
F: OrchestrationFuture,
{
inner: futures::future::JoinAll<F>,
state: Rc<RefCell<OrchestrationState>>,
is_inner: bool,
}
impl<F> JoinAll<F>
where
F: OrchestrationFuture,
{
fn new<T>(state: Rc<RefCell<OrchestrationState>>, iter: T) -> Self
where
T: IntoIterator<Item = F>,
F: OrchestrationFuture,
{
let futs: Vec<_> = iter
.into_iter()
.map(|mut f| {
f.notify_inner();
f
})
.collect();
JoinAll {
inner: join_all(futs),
state,
is_inner: false,
}
}
}
impl<F> Future for JoinAll<F>
where
F: OrchestrationFuture,
{
type Output = <futures::future::JoinAll<F> as Future>::Output;
fn poll(mut self: Pin<&mut Self>, context: &mut Context) -> Poll<Self::Output> {
let result = Future::poll(Pin::new(&mut self.inner), context);
if !self.is_inner {
if let Poll::Ready(_) = &result {
self.get_mut().state.borrow_mut().update();
}
}
result
}
}
impl<F> OrchestrationFuture for JoinAll<F>
where
F: OrchestrationFuture,
{
fn notify_inner(&mut self) {
self.is_inner = true;
}
}
struct OrchestrationState {
is_replaying: bool,
history: Vec<HistoryEvent>,
result: Rc<RefCell<ExecutionResult>>,
orchestration_index: usize,
}
impl OrchestrationState {
fn find_scheduled_activity(&mut self, activity_name: &str) -> Option<&mut HistoryEvent> {
self.history.iter_mut().find(|event| {
event.name == Some(activity_name.to_owned())
&& event.event_type == EventType::TaskScheduled
&& !event.is_processed
})
}
fn find_completed_activity(&mut self, event_id: i32) -> Option<&mut HistoryEvent> {
self.history.iter_mut().find(|event| {
event.event_type == EventType::TaskCompleted
&& event.task_scheduled_id == Some(event_id)
})
}
fn find_failed_activity(&mut self, event_id: i32) -> Option<&mut HistoryEvent> {
self.history.iter_mut().find(|event| {
event.event_type == EventType::TaskFailed && event.task_scheduled_id == Some(event_id)
})
}
fn update(&mut self) {
fn is_newer_event(event: &HistoryEvent, timestamp: DateTime<Utc>) -> bool {
event.event_type == EventType::OrchestratorStarted && event.timestamp > timestamp
}
let start = self.orchestration_index + 1;
if start >= self.history.len() {
return;
}
let current_timestamp = self.history[self.orchestration_index].timestamp;
match self.history[start..]
.iter()
.position(|event| is_newer_event(event, current_timestamp))
.map(|pos| pos + start)
{
Some(next) => {
// A new orchestration execution has occurred
self.orchestration_index = next;
self.result.borrow_mut().notify_new_execution();
let current_timestamp = self.history[self.orchestration_index].timestamp;
let start = self.orchestration_index + 1;
// Check to see if this is the last execution; if so, no more replaying
if start >= self.history.len()
|| !self.history[start..]
.iter()
.any(|event| is_newer_event(event, current_timestamp))
{
self.is_replaying = false;
}
}
None => {
self.is_replaying = false;
}
}
}
}
/// Represents the Durable Functions orchestration context binding.
///
@ -24,211 +212,128 @@ use std::task::{Context, Poll};
/// # Examples
///
/// TODO: IMPLEMENT
#[derive(Debug)]
pub struct DurableOrchestrationContext {
data: DurableOrchestrationContextData,
result: Rc<RefCell<ExecutionResult>>,
current_time: DateTime<Utc>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct DurableOrchestrationContextData {
instance_id: String,
#[serde(rename = "isReplaying")]
replaying: bool,
parent_instance_id: Option<String>,
input: Value,
history: Vec<HistoryEvent>,
/// The orchestration instance identifier.
pub instance_id: String,
/// The parent orchestration instance identifier.
pub parent_instance_id: Option<String>,
/// The input value to the orchestration.
pub input: Value,
state: Rc<RefCell<OrchestrationState>>,
}
impl DurableOrchestrationContext {
#[doc(hidden)]
pub fn new(data: TypedData, _metadata: HashMap<String, TypedData>) -> Self {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct BindingData {
instance_id: String,
is_replaying: bool,
parent_instance_id: Option<String>,
input: Value,
history: Vec<HistoryEvent>,
}
match &data.data {
Some(Data::String(s)) => {
let data: DurableOrchestrationContextData =
let data: BindingData =
from_str(s).expect("failed to parse orchestration context data");
let current_time = data
let orchestration_index = data
.history
.iter()
.find(|event| event.event_type == EventType::OrchestratorStarted)
.map(|event| event.timestamp)
.unwrap_or(Utc::now());
.position(|event| event.event_type == EventType::OrchestratorStarted)
.expect("failed to find orchestration started event");
DurableOrchestrationContext {
data,
result: Rc::new(RefCell::new(ExecutionResult::default())),
current_time,
instance_id: data.instance_id,
parent_instance_id: data.parent_instance_id,
input: data.input,
state: Rc::new(RefCell::new(OrchestrationState {
orchestration_index,
is_replaying: data.is_replaying,
history: data.history,
result: Rc::new(RefCell::new(ExecutionResult::default())),
})),
}
}
_ => panic!("expected JSON data for orchestration context data"),
}
}
/// Gets the instance ID of the currently executing orchestration.
pub fn instance_id(&self) -> &str {
&self.data.instance_id
}
/// Gets the parent instance ID of the currently executing sub-orchestration.
pub fn parent_instance_id(&self) -> Option<&str> {
self.data.parent_instance_id.as_ref().map(|id| &**id)
}
/// Gets a value indicating whether the orchestrator function is currently replaying itself.
pub fn is_replaying(&self) -> bool {
self.data.replaying
}
/// The JSON-serializeable input to pass to the orchestrator function.
pub fn input(&self) -> &Value {
&self.data.input
self.state.borrow().is_replaying
}
/// Gets the current date/time in a way that is safe for use by orchestrator functions.
pub fn current_time(&self) -> DateTime<Utc>{
self.current_time
pub fn current_time(&self) -> DateTime<Utc> {
let state = self.state.borrow();
state.history[state.orchestration_index].timestamp
}
#[doc(hidden)]
pub fn execution_result(&self) -> Rc<RefCell<ExecutionResult>> {
self.result.clone()
self.state.borrow().result.clone()
}
#[doc(hidden)]
/// Creates a future which represents a collection of the outputs of the futures given.
///
/// The returned future will drive execution for all of its underlying futures,
/// collecting the results into a destination `Vec<T>` in the same order as they
/// were provided.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub fn join_all<I>(&self, iter: I) -> JoinAll<I::Item>
where
I: IntoIterator,
I::Item: OrchestrationFuture,
{
JoinAll::new(self.state.clone(), iter)
}
/// Schedules an activity function for execution.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub fn call_activity<D>(
&mut self,
activity_name: &str,
data: D,
) -> impl Future<Output = Result<Value, String>>
) -> impl Future<Output = Result<Value, String>> + OrchestrationFuture
where
D: Into<Value>,
{
self.result.borrow_mut().add_action(Action::CallActivity {
let mut state = self.state.borrow_mut();
// Push the action on the execution result
state.result.borrow_mut().push_action(Action::CallActivity {
function_name: activity_name.to_string(),
input: data.into(),
});
let mut event_result = Option::<Result<Value, String>>::None; //ActionFuture(None); //Option::<ActionFuture<Result<Value, String>>>>::None;
let mut result: Option<Result<Value, String>> = None;
if let Some(scheduled) = self.find_scheduled_activity(activity_name) {
scheduled.processed = true;
// Attempt to resolve the activity
if let Some(scheduled) = state.find_scheduled_activity(activity_name) {
scheduled.is_processed = true;
let id = scheduled.event_id;
if let Some(completed) = self.find_completed_activity(id) {
completed.processed = true;
let value = completed.result.clone().unwrap_or_default();
event_result = Some(Ok(value));
} else if let Some(failed) = self.find_failed_activity(id) {
failed.processed = true;
let message = failed.reason.clone().unwrap_or_default();
event_result = Some(Err(message));
if let Some(completed) = state.find_completed_activity(id) {
completed.is_processed = true;
result = Some(Ok(completed
.result
.as_ref()
.map(|s| from_str(&s).unwrap_or_default())
.unwrap_or(Value::Null)));
} else if let Some(failed) = state.find_failed_activity(id) {
failed.is_processed = true;
result = Some(Err(failed.reason.clone().unwrap_or_default()));
}
}
if let Some(_) = &event_result {
self.current_time = self.next_current_time();
}
ActionFuture(event_result)
}
fn find_scheduled_activity(&mut self, activity_name: &str) -> Option<&mut HistoryEvent> {
self.data.history.iter_mut().find(|event| {
event.name == Some(activity_name.to_owned())
&& event.event_type == EventType::TaskScheduled
&& !event.processed
})
}
fn find_completed_activity(&mut self, event_id: i32) -> Option<&mut HistoryEvent> {
self.data.history.iter_mut().find(|event| {
event.event_type == EventType::TaskCompleted
&& event.task_scheduled_id == Some(event_id)
})
}
fn find_failed_activity(&mut self, event_id: i32) -> Option<&mut HistoryEvent> {
self.data.history.iter_mut().find(|event| {
event.event_type == EventType::TaskFailed && event.task_scheduled_id == Some(event_id)
})
}
fn next_current_time(&self) -> DateTime<Utc> {
let current_time = self.current_time;
self.data
.history
.iter()
.find(|event| {
event.event_type == EventType::OrchestratorStarted && event.timestamp > current_time
})
.map(|event| event.timestamp)
.unwrap_or(current_time)
ActionFuture::new(result, self.state.clone())
}
}
struct ActionFuture<T>(Option<T>);
impl<T> Future for ActionFuture<T>
where
T: Unpin,
{
type Output = T;
fn poll(self: Pin<&mut Self>, _context: &mut Context) -> Poll<T> {
if let Some(v) = self.get_mut().0.take() {
return Poll::Ready(v);
}
Poll::Pending
}
}
/*
{
"history":[
{
"EventType":12,
"EventId":-1,
"IsPlayed":false,
"Timestamp":"2019-07-18T06:22:27.016757Z"
},
{
"OrchestrationInstance":{
"InstanceId":"49497890673e4a75ab380e7a956c607b",
"ExecutionId":"5d2025984bef476bbaacefaa499a4f5f"
},
"EventType":0,
"ParentInstance":null,
"Name":"HelloWorld",
"Version":"",
"Input":"{}",
"Tags":null,
"EventId":-1,
"IsPlayed":false,
"Timestamp":"2019-07-18T06:22:26.626966Z"
}
],
"input":{
},
"instanceId":"49497890673e4a75ab380e7a956c607b",
"isReplaying":false,
"parentInstanceId":null
}
*/
#[cfg(test)]
mod tests {
use super::*;
@ -255,7 +360,8 @@ mod tests {
}
#[test]
fn new_constructs_an_orchestration_context_without_history() {
#[should_panic(expected = "failed to find orchestration started event")]
fn it_panics_if_missing_history() {
let data = TypedData {
data: Some(Data::String(
r#"{
@ -269,15 +375,7 @@ mod tests {
)),
};
let context = DurableOrchestrationContext::new(data, HashMap::new());
assert_eq!(context.instance_id(), "49497890673e4a75ab380e7a956c607b");
assert_eq!(
context.parent_instance_id(),
Some("1234123412341234123412341234")
);
assert!(!context.is_replaying());
assert_eq!(context.data.history, vec![]);
assert_eq!(context.input(), &serde_json::Value::Array(vec![]));
DurableOrchestrationContext::new(data, HashMap::new());
}
#[test]
@ -318,21 +416,21 @@ mod tests {
};
let context = DurableOrchestrationContext::new(data, HashMap::new());
assert_eq!(context.instance_id(), "49497890673e4a75ab380e7a956c607b");
assert_eq!(context.parent_instance_id(), None);
assert_eq!(context.instance_id, "49497890673e4a75ab380e7a956c607b");
assert_eq!(context.parent_instance_id, None);
assert!(!context.is_replaying());
assert_eq!(context.input(), &serde_json::Value::Array(vec![]));
assert_eq!(context.input, serde_json::Value::Array(vec![]));
assert_eq!(
context.data.history,
context.state.borrow().history,
vec![
HistoryEvent {
event_type: EventType::OrchestratorStarted,
event_id: -1,
played: true,
is_played: true,
timestamp: DateTime::<Utc>::from(
DateTime::parse_from_rfc3339("2019-07-18T06:22:27.016757Z").unwrap()
),
processed: false,
is_processed: false,
name: None,
input: None,
result: None,
@ -346,11 +444,11 @@ mod tests {
HistoryEvent {
event_type: EventType::ExecutionStarted,
event_id: -1,
played: false,
is_played: false,
timestamp: DateTime::<Utc>::from(
DateTime::parse_from_rfc3339("2019-07-18T06:22:26.626966Z").unwrap()
),
processed: false,
is_processed: false,
name: Some("HelloWorld".to_owned()),
input: Some("{}".into()),
result: None,

View File

@ -14,35 +14,36 @@ use std::{
mod actions;
mod activity_output;
mod creation_urls;
mod history;
mod management_urls;
mod orchestration_output;
pub use actions::*;
pub use creation_urls::*;
pub use history::*;
pub use management_urls::*;
pub use orchestration_output::*;
pub use self::actions::*;
pub use self::activity_output::*;
pub use self::creation_urls::*;
pub use self::management_urls::*;
pub use self::history::*;
pub use self::orchestration_output::*;
#[doc(hidden)]
#[derive(Debug, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ExecutionResult {
done: bool,
actions: Vec<Action>,
is_done: bool,
actions: Vec<Vec<Action>>,
output: Option<Value>,
custom_status: Option<Value>,
error: Option<String>,
}
impl ExecutionResult {
pub(crate) fn add_action(&mut self, action: Action) {
self.actions.push(action);
pub(crate) fn notify_new_execution(&mut self) {
self.actions.push(Vec::new());
}
pub(crate) fn push_action(&mut self, action: Action) {
if self.actions.is_empty() {
self.actions.push(Vec::new());
}
self.actions.last_mut().unwrap().push(action);
}
}
@ -92,7 +93,7 @@ where
Poll::Ready(output) => {
let mut result = result.borrow_mut();
result.output = Some(output.into_value());
result.done = true;
result.is_done = true;
}
Poll::Pending => {}
};

View File

@ -1,5 +1,6 @@
use crate::rpc::{typed_data::Data, TypedData};
use serde_json::Value;
use std::iter::FromIterator;
/// Represents the output of a Durable Functions activity function.
///
@ -15,6 +16,15 @@ where
}
}
impl FromIterator<Value> for ActivityOutput {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Value>,
{
ActivityOutput(Value::from_iter(iter))
}
}
#[doc(hidden)]
impl Into<TypedData> for ActivityOutput {
fn into(self) -> TypedData {

View File

@ -17,13 +17,12 @@ pub struct HistoryEvent {
pub(crate) event_id: i32,
#[serde(alias = "IsPlayed")]
pub(crate) played: bool,
pub(crate) is_played: bool,
pub(crate) timestamp: DateTime<Utc>,
#[serde(default, alias = "IsProcessed")]
pub(crate) processed: bool,
#[serde(skip)]
pub(crate) is_processed: bool,
// EventRaised, ExecutionStarted, SubOrchestrationInstanceCreated, TaskScheduled
pub(crate) name: Option<String>,
@ -32,7 +31,7 @@ pub struct HistoryEvent {
pub(crate) input: Option<Value>,
//SubOrchestrationInstanceCompleted, TaskCompleted
pub(crate) result: Option<Value>,
pub(crate) result: Option<String>,
// SubOrchestrationInstanceCompleted , SubOrchestrationInstanceFailed, TaskCompleted,TaskFailed
pub(crate) task_scheduled_id: Option<i32>,

View File

@ -1,5 +1,6 @@
use crate::durable::IntoValue;
use serde_json::Value;
use std::iter::FromIterator;
/// Represents the output of a Durable Functions orchestration function.
///
@ -15,6 +16,15 @@ where
}
}
impl FromIterator<Value> for OrchestrationOutput {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Value>,
{
OrchestrationOutput(Value::from_iter(iter))
}
}
impl IntoValue for OrchestrationOutput {
fn into_value(self) -> Value {
self.0

View File

@ -6,6 +6,8 @@
//!
//! * [Blob trigger](bindings/struct.BlobTrigger.html)
//! * [Cosmos DB trigger](bindings/struct.CosmosDbTrigger.html)
//! * [Durable Activity trigger](bindings/struct.DurableOrchestrationContext.html)
//! * [Durable Orchestration trigger](bindings/struct.DurableOrchestrationContext.html)
//! * [Event Grid trigger](bindings/struct.EventGridEvent.html)
//! * [Event Hub trigger](bindings/struct.EventHubTrigger.html)
//! * [Generic trigger](bindings/struct.GenericTrigger.html)
@ -18,6 +20,7 @@
//!
//! * [Blob input](bindings/struct.Blob.html)
//! * [Cosmos DB input](bindings/struct.CosmosDbDocument.html)
//! * [Durable orchestration client input](bindings/struct.DurableOrchestrationClient.html)
//! * [Generic input](bindings/struct.GenericInput.html)
//! * [SignalR connection info input](bindings/struct.SignalRConnectionInfo.html)
//! * [Table input](bindings/struct.Table.html)
@ -87,6 +90,7 @@
#![deny(unused_extern_crates)]
#![deny(missing_docs)]
#![cfg_attr(test, recursion_limit = "128")]
#![feature(async_await)]
#[doc(no_inline)]
pub use azure_functions_codegen::export;

View File

@ -0,0 +1,16 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "attach",
"name": "Debug",
"windows": {
"program": "durable-functions-example.exe"
},
"program": "durable-functions-example",
"preLaunchTask": "Launch Azure Functions Application",
"postDebugTask": "Terminate Azure Functions Application"
}
]
}

View File

@ -0,0 +1,49 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Launch Azure Functions Application",
"type": "shell",
"command": "cargo",
"args": [
"func",
"run",
"--",
"--features",
"unstable"
],
"presentation": {
"reveal": "always",
"clear": true,
"focus": true
},
"problemMatcher": [
{
"owner": "azureFunctions",
"pattern": [
{
"regexp": "\\b\\B",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "^Azure Functions Core Tools",
"endsPattern": "^Application started."
}
}
],
"isBackground": true
},
{
"label": "Terminate Azure Functions Application",
"type": "process",
"command":"${command:workbench.action.tasks.terminate}",
"args": [
"Launch Azure Functions Application"
]
}
]
}

View File

@ -8,6 +8,7 @@ edition = "2018"
azure-functions = { path = "../../azure-functions" }
log = "0.4.6"
futures-preview = { version = "0.3.0-alpha.17", optional = true }
serde_json = "1.0.40"
[features]
unstable = ["azure-functions/unstable", "futures-preview"]

View File

@ -1,18 +1,29 @@
use azure_functions::{bindings::DurableOrchestrationContext, durable::OrchestrationOutput, func};
use futures::future::join_all;
use log::warn;
use serde_json::Value;
#[func]
pub async fn hello_world(mut context: DurableOrchestrationContext) -> OrchestrationOutput {
// join_all(
// [
// context.call_activity("say_hello", "Tokyo"),
// context.call_activity("say_hello", "London"),
// context.call_activity("say_hello", "Seattle"),
// ]
// .into_iter(),
// )
// .await
// .map(|r| r.unwrap())
// .into()
unimplemented!()
if !context.is_replaying() {
warn!("Orchestration started at {}.", context.current_time());
}
let activities = vec![
context.call_activity("say_hello", "Tokyo"),
context.call_activity("say_hello", "London"),
context.call_activity("say_hello", "Seattle"),
];
let result: Vec<_> = context
.join_all(activities)
.await
.into_iter()
.map(|r| r.unwrap_or_else(|e| Value::from(format!("Activity failed: {}", e))))
.collect();
if !context.is_replaying() {
warn!("Orchestration completed at {}.", context.current_time());
}
result.into()
}

View File

@ -1,11 +1,10 @@
use azure_functions::{bindings::DurableActivityContext, durable::ActivityOutput, func};
#[func]
pub async fn say_hello(_context: DurableActivityContext) -> ActivityOutput {
// format!(
// "Hello {}!",
// context.input().as_str().expect("expected a string input")
// )
// .into()
unimplemented!()
pub fn say_hello(context: DurableActivityContext) -> ActivityOutput {
format!(
"Hello {}!",
context.input.as_str().expect("expected a string input")
)
.into()
}

View File

@ -2,12 +2,12 @@ use azure_functions::{
bindings::{DurableOrchestrationClient, HttpRequest, HttpResponse},
func,
};
use serde_json::Value;
#[func]
pub async fn start(_req: HttpRequest, _client: DurableOrchestrationClient) -> HttpResponse {
// match client.start_new("hello_world").await {
// Ok(_) => "Orchestration started.".into(),
// Err(e) => format!("Failed to start orchestration: {}", e).into()
// }
unimplemented!()
pub async fn start(_req: HttpRequest, client: DurableOrchestrationClient) -> HttpResponse {
match client.start_new("hello_world", None, Value::Null).await {
Ok(_) => "Orchestration started.".into(),
Err(e) => format!("Failed to start orchestration: {}", e).into(),
}
}