Compare commits
7 commits
0be4e33b36
...
28e6e76008
Author | SHA1 | Date | |
---|---|---|---|
|
28e6e76008 | ||
|
417f01d484 | ||
|
851e9a6711 | ||
|
634ba4a2ba | ||
|
35e89d7c7d | ||
|
11d6734d29 | ||
|
cdc191a3a1 |
12 changed files with 387 additions and 780 deletions
657
Cargo.lock
generated
657
Cargo.lock
generated
|
@ -2,244 +2,28 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gg-broadcast"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"maelstrom-node",
|
||||
"nebkor-maelstrom",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gg-echo"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"maelstrom-node",
|
||||
"tokio",
|
||||
"nebkor-maelstrom",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gg-uid"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"maelstrom-node",
|
||||
"nebkor-maelstrom",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -249,130 +33,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
name = "nebkor-maelstrom"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "maelstrom-node"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f5c71562438987c4386067f65426150b918f2e000c7c851256ec8adea01b516"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"simple-error",
|
||||
"tokio",
|
||||
"tokio-context",
|
||||
"tokio-util",
|
||||
"serde_repr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -386,62 +59,12 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.202"
|
||||
|
@ -474,98 +97,10 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
name = "serde_repr"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simple-error"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8542b68b8800c3cda649d2c72d688b6907b30f1580043135d61669d4aad1c175"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-context"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf0b8394dd5ca9a1b726c629390154c19222dfd7467a4b56f1ced90adee3958"
|
||||
dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -573,16 +108,14 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.11"
|
||||
name = "syn"
|
||||
version = "2.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
|
||||
checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -590,157 +123,3 @@ name = "unicode-ident"
|
|||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[workspace]
|
||||
members = ["gg-echo", "gg-uid", "gg-broadcast"]
|
||||
members = ["gg-echo", "gg-uid", "gg-broadcast", "nebkor-maelstrom"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
|
@ -8,7 +8,4 @@ authors = ["joe ardent"]
|
|||
license-file = "LICENSE.md"
|
||||
|
||||
[workspace.dependencies]
|
||||
async-trait = "0.1"
|
||||
maelstrom-node = "0.1"
|
||||
tokio = { version = "1", default-features = false, features = ["io-util", "io-std", "rt-multi-thread", "macros"] }
|
||||
serde_json = "1"
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
Working through the [Fly.io distributed systems challenge](https://fly.io/dist-sys/), in Rust.
|
||||
|
||||
The `nebkor-maelstrom` crate is meant to be roughly equivalent to the Go Maelstrom.Node package, and
|
||||
provides serde-backed data structures for messages as well as runner for processing messages from
|
||||
the Maelstrom network. See `gg-echo/src/main.rs` for the simplest possible use of it.
|
||||
|
|
|
@ -6,7 +6,5 @@ authors.workspace = true
|
|||
license-file.workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-trait.workspace = true
|
||||
maelstrom-node.workspace = true
|
||||
serde_json.workspace = true
|
||||
tokio.workspace = true
|
||||
nebkor-maelstrom = { path = "../nebkor-maelstrom" }
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
use async_trait::async_trait;
|
||||
use maelstrom::protocol::Message;
|
||||
use maelstrom::{done, protocol::MessageBody, Node, Result, Runtime};
|
||||
use serde_json::{Map, Value};
|
||||
use std::borrow::BorrowMut;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{collections::HashMap, rc::Rc, sync::Mutex};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let handler = Arc::new(BCaster::default());
|
||||
let _ = Runtime::new()
|
||||
.with_handler(handler)
|
||||
.run()
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
use nebkor_maelstrom::{protocol::Payload, Body, Message, Node, Runner};
|
||||
|
||||
fn main() {
|
||||
let out = std::io::stdout().lock();
|
||||
let input = std::io::stdin().lock();
|
||||
|
||||
let node = BCaster::default();
|
||||
let node = Rc::new(Mutex::new(node));
|
||||
|
||||
let runner = Runner::new(out, node);
|
||||
|
||||
runner.run(input);
|
||||
}
|
||||
|
||||
type Store = Arc<Mutex<HashMap<String, i64>>>;
|
||||
type Gossips = Arc<Mutex<HashMap<(u64, String), MessageBody>>>;
|
||||
type Store = HashMap<String, i64>;
|
||||
type Gossips = HashMap<u64, Message>;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct BCaster {
|
||||
|
@ -25,96 +23,83 @@ struct BCaster {
|
|||
pub gossips: Gossips,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Node for BCaster {
|
||||
async fn process(&self, runtime: Runtime, req: Message) -> Result<()> {
|
||||
let typ = req.get_type();
|
||||
fn handle(&mut self, runner: &Runner, req: &Message) {
|
||||
let typ = req.body.typ.as_str();
|
||||
let frm = req.src.as_str();
|
||||
let mid = req.body.msg_id;
|
||||
let key = format!("{frm}{mid}");
|
||||
let nid = runner.node_id();
|
||||
let nid = nid.as_str();
|
||||
let key = format!("{frm}-{mid}");
|
||||
let key = key.as_str();
|
||||
|
||||
{
|
||||
let gossips: Vec<((_, String), MessageBody)> = {
|
||||
let g = self.gossips.lock().unwrap();
|
||||
g.clone().into_iter().collect()
|
||||
};
|
||||
|
||||
for ((_, node), gossip) in gossips.into_iter() {
|
||||
runtime.send(node, gossip).await.unwrap_or_default();
|
||||
for (_, gossip) in self.gossips.iter() {
|
||||
runner.send(gossip.clone());
|
||||
}
|
||||
}
|
||||
|
||||
match typ {
|
||||
"gossip_ok" => {
|
||||
let id = req.body.in_reply_to;
|
||||
self.gossips.remove(&id);
|
||||
}
|
||||
"broadcast" => {
|
||||
let val = req.body.extra.get("message").and_then(|v| v.as_i64());
|
||||
let val = req.body.payload.get("message").and_then(|v| v.as_i64());
|
||||
if let Some(val) = val {
|
||||
{
|
||||
// there's only one thread, safe to unwrap
|
||||
let mut guard = self.store.lock().unwrap();
|
||||
guard.borrow_mut().entry(key.to_owned()).or_insert(val);
|
||||
self.store.entry(key.to_owned()).or_insert(val);
|
||||
}
|
||||
|
||||
let extra: Map<String, Value> = [
|
||||
let extra: Payload = [
|
||||
("key".to_string(), key.into()),
|
||||
("val".to_string(), val.into()),
|
||||
]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let gossip = MessageBody::from_extra(extra).with_type("gossip");
|
||||
for node in runtime.neighbours() {
|
||||
let id = runtime.next_msg_id();
|
||||
let gossip = gossip.clone().and_msg_id(id);
|
||||
{
|
||||
let mut g = self.gossips.lock().unwrap();
|
||||
g.insert((id, node.to_owned()), gossip.clone());
|
||||
}
|
||||
runtime.send(node, gossip).await?;
|
||||
}
|
||||
let gossip = Body::from_type("gossip").with_payload(extra);
|
||||
for node in runner.nodes().iter().filter(|n| n.as_str() != nid) {
|
||||
let id = runner.next_msg_id();
|
||||
let gossip = gossip.clone().with_msg_id(id);
|
||||
let msg = Message {
|
||||
body: gossip,
|
||||
src: nid.to_string(),
|
||||
dest: node.to_string(),
|
||||
};
|
||||
self.gossips.insert(id, msg.clone());
|
||||
|
||||
let body = MessageBody::new().with_type("broadcast_ok");
|
||||
return runtime.reply(req, body).await;
|
||||
runner.send(msg);
|
||||
}
|
||||
let body = Body::from_type("broadcast_ok");
|
||||
runner.reply(req, body);
|
||||
}
|
||||
}
|
||||
"read" => {
|
||||
let vals = {
|
||||
let g = self.store.lock().unwrap();
|
||||
g.values().cloned().collect::<Vec<_>>()
|
||||
};
|
||||
let body = MessageBody::from_extra(
|
||||
[("messages".to_string(), vals.into())]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
)
|
||||
.with_type("read_ok");
|
||||
return runtime.reply(req, body).await;
|
||||
let vals = self.store.values().cloned().collect::<Vec<_>>();
|
||||
|
||||
let payload: Payload = [("messages".to_string(), vals.into())]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let body = Body::from_type("read_ok").with_payload(payload);
|
||||
|
||||
runner.reply(req, body);
|
||||
}
|
||||
"topology" => {
|
||||
let body = MessageBody::new().with_type("topology_ok");
|
||||
return runtime.reply(req, body).await;
|
||||
let body = Body::from_type("topology_ok");
|
||||
runner.reply(req, body);
|
||||
}
|
||||
"gossip" => {
|
||||
let key = req.body.extra.get("key").unwrap().as_str().unwrap();
|
||||
let val = req.body.extra.get("val").unwrap().as_i64().unwrap();
|
||||
{
|
||||
// there's only one thread, safe to unwrap
|
||||
let mut guard = self.store.lock().unwrap();
|
||||
guard.borrow_mut().entry(key.to_string()).or_insert(val);
|
||||
}
|
||||
let body = MessageBody::new().with_type("gossip_ok");
|
||||
return runtime.reply(req, body).await;
|
||||
}
|
||||
"gossip_ok" => {
|
||||
let id = req.body.in_reply_to;
|
||||
let key = (id, frm.to_owned());
|
||||
{
|
||||
let mut g = self.gossips.lock().unwrap();
|
||||
g.remove(&key);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let key = req.body.payload.get("key").unwrap().as_str().unwrap();
|
||||
let val = req.body.payload.get("val").unwrap().as_i64().unwrap();
|
||||
|
||||
done(runtime, req)
|
||||
self.store.entry(key.to_string()).or_insert(val);
|
||||
let body = Body::from_type("gossip_ok");
|
||||
runner.reply(req, body);
|
||||
}
|
||||
_ => {
|
||||
eprintln!("unknown type: {req:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,5 @@ version.workspace = true
|
|||
authors.workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-trait.workspace = true
|
||||
maelstrom-node.workspace = true
|
||||
tokio.workspace = true
|
||||
serde_json.workspace = true
|
||||
nebkor-maelstrom = { path = "../nebkor-maelstrom" }
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
use async_trait::async_trait;
|
||||
use maelstrom::protocol::Message;
|
||||
use maelstrom::{done, Node, Result, Runtime};
|
||||
use std::sync::Arc;
|
||||
use std::{rc::Rc, sync::Mutex};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let handler = Arc::new(Handler::default());
|
||||
let _ = Runtime::new()
|
||||
.with_handler(handler)
|
||||
.run()
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
}
|
||||
use nebkor_maelstrom::{Body, Message, Node, Runner};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct Handler {}
|
||||
struct Echo;
|
||||
|
||||
#[async_trait]
|
||||
impl Node for Handler {
|
||||
async fn process(&self, runtime: Runtime, req: Message) -> Result<()> {
|
||||
if req.get_type() == "echo" {
|
||||
let echo = req.body.clone().with_type("echo_ok");
|
||||
return runtime.reply(req, echo).await;
|
||||
impl Node for Echo {
|
||||
fn handle(&mut self, runner: &Runner, msg: &Message) {
|
||||
let typ = &msg.body.typ;
|
||||
match typ.as_str() {
|
||||
"echo" => {
|
||||
let body = Body::from_type("echo_ok").with_payload(msg.body.payload.clone());
|
||||
runner.reply(&msg, body);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
done(runtime, req)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let out = std::io::stdout().lock();
|
||||
let input = std::io::stdin().lock();
|
||||
|
||||
let node = Echo;
|
||||
let node = Rc::new(Mutex::new(node));
|
||||
|
||||
let runner = Runner::new(out, node);
|
||||
|
||||
runner.run(input);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,5 @@ authors.workspace = true
|
|||
license-file.workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-trait.workspace = true
|
||||
maelstrom-node.workspace = true
|
||||
serde_json.workspace = true
|
||||
tokio.workspace = true
|
||||
nebkor-maelstrom = { path = "../nebkor-maelstrom" }
|
||||
|
|
|
@ -1,37 +1,35 @@
|
|||
use async_trait::async_trait;
|
||||
use maelstrom::protocol::Message;
|
||||
use maelstrom::{done, protocol::MessageBody, Node, Result, Runtime};
|
||||
use serde_json::{Map, Value};
|
||||
use std::sync::Arc;
|
||||
use std::{rc::Rc, sync::Mutex};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let handler = Arc::new(Handler);
|
||||
let _ = Runtime::new()
|
||||
.with_handler(handler)
|
||||
.run()
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
use nebkor_maelstrom::{protocol::Payload, Body, Message, Node, Runner};
|
||||
|
||||
fn main() {
|
||||
let out = std::io::stdout().lock();
|
||||
let input = std::io::stdin().lock();
|
||||
|
||||
let node = GenUid;
|
||||
let node = Rc::new(Mutex::new(node));
|
||||
|
||||
let runner = Runner::new(out, node);
|
||||
|
||||
runner.run(input);
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct Handler;
|
||||
struct GenUid;
|
||||
|
||||
#[async_trait]
|
||||
impl Node for Handler {
|
||||
async fn process(&self, runtime: Runtime, req: Message) -> Result<()> {
|
||||
let id = runtime.node_id();
|
||||
let mid = runtime.next_msg_id();
|
||||
if req.get_type() == "generate" {
|
||||
let extra: Map<String, Value> = [("id".to_string(), format!("{id}{mid}").into())]
|
||||
impl Node for GenUid {
|
||||
fn handle(&mut self, runner: &Runner, msg: &Message) {
|
||||
let id = runner.node_id();
|
||||
let mid = runner.next_msg_id();
|
||||
if msg.body.typ == "generate" {
|
||||
let payload: Payload = [("id".to_string(), format!("{id}{mid}").into())]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let body = MessageBody::from_extra(extra)
|
||||
.with_type("generate_ok")
|
||||
.and_msg_id(mid);
|
||||
return runtime.reply(req, body).await;
|
||||
}
|
||||
let body = Body::from_type("generate_ok")
|
||||
.with_msg_id(mid)
|
||||
.with_payload(payload);
|
||||
|
||||
done(runtime, req)
|
||||
runner.reply(msg, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
nebkor-maelstrom/Cargo.toml
Normal file
11
nebkor-maelstrom/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "nebkor-maelstrom"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license-file.workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde_json.workspace = true
|
||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
||||
serde_repr = "0.1"
|
121
nebkor-maelstrom/src/lib.rs
Normal file
121
nebkor-maelstrom/src/lib.rs
Normal file
|
@ -0,0 +1,121 @@
|
|||
use std::{
|
||||
cell::OnceCell,
|
||||
io::{BufRead, StdinLock, StdoutLock, Write},
|
||||
rc::Rc,
|
||||
sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
Mutex,
|
||||
},
|
||||
};
|
||||
|
||||
pub mod protocol;
|
||||
pub use protocol::{Body, Message};
|
||||
|
||||
pub type DynNode = Rc<Mutex<dyn Node>>;
|
||||
|
||||
pub trait Node {
|
||||
fn handle(&mut self, runner: &Runner, msg: &Message);
|
||||
}
|
||||
|
||||
pub struct Runner<'io> {
|
||||
msg_id: AtomicU64,
|
||||
node: DynNode,
|
||||
node_id: OnceCell<String>,
|
||||
nodes: OnceCell<Vec<String>>,
|
||||
output: Mutex<StdoutLock<'io>>,
|
||||
steps: AtomicU64,
|
||||
}
|
||||
|
||||
impl<'io> Runner<'io> {
|
||||
pub fn new(output: StdoutLock<'io>, node: DynNode) -> Self {
|
||||
Runner {
|
||||
output: Mutex::new(output),
|
||||
node,
|
||||
msg_id: AtomicU64::new(1),
|
||||
nodes: OnceCell::new(),
|
||||
node_id: OnceCell::new(),
|
||||
steps: AtomicU64::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self, input: StdinLock) {
|
||||
for line in input.lines().map_while(Result::ok) {
|
||||
if let Ok(msg) = serde_json::from_str::<Message>(&line) {
|
||||
let typ = &msg.body.typ;
|
||||
if let "init" = typ.as_str() {
|
||||
self.init(&msg);
|
||||
let body = Body::from_type("init_ok");
|
||||
self.reply(&msg, body);
|
||||
} else {
|
||||
let mut n = self.node.lock().unwrap();
|
||||
n.handle(self, &msg);
|
||||
}
|
||||
}
|
||||
self.steps.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn node_id(&self) -> String {
|
||||
self.node_id.get().cloned().unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn next_msg_id(&self) -> u64 {
|
||||
self.msg_id.fetch_add(1, Ordering::SeqCst)
|
||||
}
|
||||
|
||||
pub fn nodes(&self) -> &[String] {
|
||||
self.nodes.get().unwrap()
|
||||
}
|
||||
|
||||
pub fn init(&self, msg: &Message) {
|
||||
let node_id = msg
|
||||
.body
|
||||
.payload
|
||||
.get("node_id")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
let nodes = msg
|
||||
.body
|
||||
.payload
|
||||
.get("node_ids")
|
||||
.unwrap()
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|s| s.as_str().unwrap().to_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let _ = self.node_id.get_or_init(|| node_id.to_owned());
|
||||
let _ = self.nodes.get_or_init(|| nodes.to_vec());
|
||||
}
|
||||
|
||||
pub fn reply(&self, req: &Message, body: Body) {
|
||||
let mut body = body;
|
||||
let src = self.node_id.get().unwrap().to_owned();
|
||||
let dest = req.src.clone();
|
||||
let in_reply_to = req.body.msg_id;
|
||||
body.in_reply_to = in_reply_to;
|
||||
let msg = Message { src, dest, body };
|
||||
self.send(msg);
|
||||
}
|
||||
|
||||
pub fn send(&self, msg: Message) {
|
||||
let mut msg = msg;
|
||||
if msg.body.msg_id == 0 {
|
||||
let mid = self.next_msg_id();
|
||||
msg.body.msg_id = mid;
|
||||
}
|
||||
let msg = serde_json::to_string(&msg).unwrap();
|
||||
self.writeln(&msg);
|
||||
}
|
||||
|
||||
fn writeln(&self, msg: &str) {
|
||||
let mut out = self.output.lock().unwrap();
|
||||
let msg = format!("{msg}\n");
|
||||
out.write_all(msg.as_bytes()).unwrap();
|
||||
out.flush().unwrap();
|
||||
}
|
||||
}
|
116
nebkor-maelstrom/src/protocol.rs
Normal file
116
nebkor-maelstrom/src/protocol.rs
Normal file
|
@ -0,0 +1,116 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Map, Value};
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
|
||||
pub type Payload = Map<String, Value>;
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct Message {
|
||||
pub src: String,
|
||||
pub dest: String,
|
||||
pub body: Body,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
#[serde(rename = "type")]
|
||||
pub typ: String,
|
||||
#[serde(default, skip_serializing_if = "u64_zero_by_ref")]
|
||||
pub msg_id: u64,
|
||||
#[serde(default, skip_serializing_if = "u64_zero_by_ref")]
|
||||
pub in_reply_to: u64,
|
||||
#[serde(flatten)]
|
||||
pub payload: Payload,
|
||||
}
|
||||
|
||||
impl Body {
|
||||
pub fn from_type(typ: &str) -> Self {
|
||||
Body {
|
||||
typ: typ.to_string(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_msg_id(self, msg_id: u64) -> Self {
|
||||
let mut b = self;
|
||||
b.msg_id = msg_id;
|
||||
b
|
||||
}
|
||||
|
||||
pub fn with_in_reply_to(self, in_reply_to: u64) -> Self {
|
||||
let mut b = self;
|
||||
b.in_reply_to = in_reply_to;
|
||||
b
|
||||
}
|
||||
|
||||
pub fn with_payload(self, payload: Payload) -> Self {
|
||||
let mut b = self;
|
||||
b.payload = payload;
|
||||
b
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_ok(msg_id: u64, in_reply_to: u64) -> Body {
|
||||
Body::from_type("init_ok")
|
||||
.with_msg_id(msg_id)
|
||||
.with_in_reply_to(in_reply_to)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ErrorCode {
|
||||
Definite(DefiniteError),
|
||||
Indefinite(IndefiniteError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize_repr, Deserialize_repr)]
|
||||
#[repr(u64)]
|
||||
pub enum DefiniteError {
|
||||
NodeNotFound = 2,
|
||||
NotSupported = 10,
|
||||
TemporarilyUnavailable = 11,
|
||||
MalformedRequest = 12,
|
||||
Abort = 14,
|
||||
KeyNotFound = 20,
|
||||
KeyAlreadyExists = 21,
|
||||
PreconditionFailed = 22,
|
||||
TxnConflict = 30,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize_repr, Deserialize_repr)]
|
||||
#[repr(u64)]
|
||||
pub enum IndefiniteError {
|
||||
Timeout = 0,
|
||||
Crash = 13,
|
||||
}
|
||||
|
||||
pub fn error(msg_id: u64, in_reply_to: u64, code: ErrorCode, text: Option<&str>) -> Body {
|
||||
Body {
|
||||
typ: "error".to_string(),
|
||||
msg_id,
|
||||
in_reply_to,
|
||||
payload: [
|
||||
("code".to_string(), serde_json::to_value(code).unwrap()),
|
||||
("text".to_string(), serde_json::to_value(text).unwrap()),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||
fn u64_zero_by_ref(num: &u64) -> bool {
|
||||
*num == 0
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn error_codes() {
|
||||
let ec = ErrorCode::Definite(DefiniteError::Abort);
|
||||
let e = serde_json::to_string(&ec).unwrap();
|
||||
assert_eq!(&e, "14");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue