~qaul/community

ratman/netmod: Async interface for netmods v1 PROPOSED

Katharina Fey: 3
 ratman/netmod: Async interface for netmods
 netmod-mem: Update to async Endpoint interface
 netmod: first implementation of a blocking netmod::ffi interface

 14 files changed, 173 insertions(+), 132 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~qaul/community/patches/9492/mbox | git am -3
Learn more about email & git

[PATCH 1/3] ratman/netmod: Async interface for netmods Export this patch

From: Leonora Tindall <nora@nora.codes>

This uses the #[async_trait] macro from async_trait 0.1, which is
currently the recommended way to do async fn's in traits. However it is
not optimal for performance since it requires indirection and we can
hope that this requirement will be removed eventually.

The poll() and listen() functions are replaced with a single function,
next(), which uses a poll-based interface on an &mut of the netmod,
meaning that only one future from next() can be out at once.
---
 Cargo.lock                    | 71 +++++++++++++++++++++--------------
 ratman/netmod/Cargo.toml      |  2 +-
 ratman/netmod/src/endpoint.rs | 36 ++++--------------
 3 files changed, 50 insertions(+), 59 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index d3512bb..9fb91b2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -36,7 +36,7 @@ name = "async-std"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "async-task 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "async-task 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -50,17 +50,28 @@ dependencies = [
 "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
 "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
 "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
 "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "async-task"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "async-trait"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "proc-macro2 1.0.7 (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.13 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
@@ -269,12 +280,12 @@ dependencies = [

[[package]]
name = "getrandom"
version = "0.1.13"
version = "0.1.14"
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.66 (registry+https://github.com/rust-lang/crates.io-index)",
 "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
@@ -298,7 +309,7 @@ dependencies = [

[[package]]
name = "hermit-abi"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -423,7 +434,7 @@ dependencies = [
 "conjoiner-engine 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "libqaul-ipc 0.1.0",
 "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 "ratman 0.0.0",
 "ratman-identity 0.1.0",
@@ -509,7 +520,7 @@ dependencies = [

[[package]]
name = "mime"
version = "0.3.14"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
@@ -618,7 +629,7 @@ name = "num_cpus"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]

@@ -687,7 +698,7 @@ dependencies = [

[[package]]
name = "pin-project-lite"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
@@ -726,7 +737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "proc-macro2"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -737,7 +748,7 @@ name = "qaul-files"
version = "0.1.0"
dependencies = [
 "libqaul 0.1.0",
 "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
 "ratman-identity 0.1.0",
]

@@ -767,7 +778,7 @@ name = "quote"
version = "1.0.2"
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)",
 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
@@ -793,7 +804,7 @@ name = "rand"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
 "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
 "libc 0.2.66 (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)",
@@ -836,7 +847,7 @@ name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
 "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
@@ -928,6 +939,7 @@ dependencies = [
name = "ratman-netmod"
version = "0.1.0"
dependencies = [
 "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
 "conjoiner-engine 1.2.4-alpha.0 (git+https://git.open-communication.net/qaul/conjoiner-engine)",
 "ratman-identity 0.1.0",
 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1011,9 +1023,9 @@ name = "serde_derive"
version = "1.0.104"
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)",
 "proc-macro2 1.0.7 (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.11 (registry+https://github.com/rust-lang/crates.io-index)",
 "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
@@ -1053,10 +1065,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "syn"
version = "1.0.11"
version = "1.0.13"
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)",
 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1163,7 +1175,7 @@ dependencies = [

[[package]]
name = "wasi"
version = "0.7.0"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
@@ -1209,7 +1221,8 @@ dependencies = [
"checksum anneal 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d5a664b2ede788e9026010ae9839bf5d0a603ddde819df16f44f0cc7817dbf08"
"checksum as-slice 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "be6b7e95ac49d753f19cab5a825dea99a1149a04e4e3230b33ae16e120954c04"
"checksum async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf6039b315300e057d198b9d3ab92ee029e31c759b7f1afae538145e6f18a3e"
"checksum async-task 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "abdb6048336bef96e8c8fc5573536c5cc5b391fbfd0980349959b7c3f7a40d19"
"checksum async-task 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "698d676dbe689c72ebd57de09e7eb0db9f38fd8dd0cf6c5dc8d76971ebecde1b"
"checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c"
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
@@ -1237,10 +1250,10 @@ dependencies = [
"checksum futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum hash32 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
"checksum heapless 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f339aa7d51777fc0af6aa7cbeb277dfc6e6c029cbdeda48d0fbb92c2337f0e69"
"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7"
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
"checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e"
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
"checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273"
@@ -1260,7 +1273,7 @@ dependencies = [
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
"checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf"
"checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
"checksum mime_guess 1.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0d977de9ee851a0b16e932979515c0f3da82403183879811bc97d50bd9cc50f7"
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
@@ -1278,13 +1291,13 @@ dependencies = [
"checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
"checksum pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0af6cbca0e6e3ce8692ee19fb8d734b641899e07b68eb73e9bbbd32f1703991"
"checksum pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422"
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
"checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0"
"checksum postcard 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f61f42c9617f3d7b447ee300bf80cb16c7cd7b28ca88555822793f073f69719f"
"checksum postcard-cobs 0.1.5-pre (registry+https://github.com/rust-lang/crates.io-index)" = "7c68cb38ed13fd7bc9dd5db8f165b7c8d9c1a315104083a2b10f11354c2af97f"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
@@ -1318,7 +1331,7 @@ dependencies = [
"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56"
@@ -1332,7 +1345,7 @@ dependencies = [
"checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f"
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
diff --git a/ratman/netmod/Cargo.toml b/ratman/netmod/Cargo.toml
index b5b30d5..4ca5413 100644
--- a/ratman/netmod/Cargo.toml
+++ b/ratman/netmod/Cargo.toml
@@ -14,4 +14,4 @@ identity = { path = "../identity", features = ["digest"], package = "ratman-iden
conjoiner = { git = "https://git.open-communication.net/qaul/conjoiner-engine", package = "conjoiner-engine" }
serde = { version = "1.0", features = ["derive"] }
twox-hash = "1.5"

async-trait = "0.1"
diff --git a/ratman/netmod/src/endpoint.rs b/ratman/netmod/src/endpoint.rs
index 0721822..1ea1986 100644
--- a/ratman/netmod/src/endpoint.rs
+++ b/ratman/netmod/src/endpoint.rs
@@ -1,11 +1,13 @@
//! Endpoint abstraction module

use crate::{Frame, Result};
use async_trait::async_trait;

/// A `RATMAN` `netmod` endpoint describes a networking interface
///
/// For more information about the rationale of this interface, check
/// the `netmod` crate documentation!
#[async_trait]
pub trait Endpoint {
    /// Return a desired frame size in bytes
    ///
@@ -41,34 +43,10 @@ pub trait Endpoint {
    ///
    /// Send errors _can_ be encoded in the return value, and so if
    /// physically a `Frame` is too large for the transport layer,
    /// using the error value `Error::FrameTooLarge` is permitted. 
    ///
    /// **NOTE: ASYNC THIS**
    fn send(&mut self, frame: Frame, target: i16) -> Result<()>;
    /// using the error value `Error::FrameTooLarge` is permitted.
    async fn send(&mut self, frame: Frame, target: i16) -> Result<()>;

    /// Get next available Frame, without blocking
    ///
    /// Because the poll might not have data to return, a valid, but
    /// not fatal return is `Ok(None)`, which means that the
    /// connection is healthy, but in the last poll cycle no new data
    /// was transmitted.
    ///
    /// The target ID is a way to instruct a netmod where to send a
    /// frame in a one-to-many mapping.  When implementing a
    /// one-to-one endpoint, this ID can be ignored (set to 0).
    ///
    /// **IMPORTANT** setting the target to `-1` should result in a
    /// broadcast on that channel.
    ///
    /// **NOTE: ASYNC THIS**
    fn poll(&mut self) -> Result<Option<(Frame, i16)>>;

    /// Setup a listener via a handler function
    ///
    /// This function assumes that relevant state can be captured via
    /// the handler's closure, meaning that no data needs to be
    /// returned from the function for it to process incoming frames.
    ///
    /// For a more "classical" poll function, see `poll` instead
    fn listen(&mut self, handler: Box<dyn FnMut(Frame, i16) -> Result<()>>) -> Result<()>;
    /// Get next available Frame from the network, or an error explaining why that's
    /// not a possibility.
    async fn next(&mut self) -> Result<(Frame, i16)>;
}
-- 
2.24.0

[PATCH 2/3] netmod-mem: Update to async Endpoint interface Export this patch

From: Leonora Tindall <nora@nora.codes>

This provides rudamentary support for the new async Endpoint interface
in netmod-mem, but does not take full advantage of the new, expanded
features that such an interface provides. Specifically, new work in
BroadcastMedium is needed to ensure that async programs can take full
advantage of its API.
---
 Cargo.lock                               | 13 ++++++++
 netmod-mem/Cargo.toml                    |  5 +++
 netmod-mem/src/lib.rs                    | 38 ++++++++-------------
 netmod-mem/src/media.rs                  |  1 -
 netmod-mem/src/media/broadcast_medium.rs |  9 ++---
 netmod-mem/tests/basic.rs                | 27 ++++++++-------
 netmod-mem/tests/broadcast.rs            | 42 +++++++++++-------------
 7 files changed, 70 insertions(+), 65 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 9fb91b2..29b7658 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -31,11 +31,21 @@ dependencies = [
 "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "async-attributes"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "async-std"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 "async-task 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -592,6 +602,8 @@ dependencies = [
name = "netmod-mem"
version = "0.1.0"
dependencies = [
 "async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
 "ratman-identity 0.1.0",
 "ratman-netmod 0.1.0",
]
@@ -1220,6 +1232,7 @@ dependencies = [
"checksum alexandria 0.1.0 (git+https://git.open-communication.net/qaul/alexandria)" = "<none>"
"checksum anneal 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d5a664b2ede788e9026010ae9839bf5d0a603ddde819df16f44f0cc7817dbf08"
"checksum as-slice 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "be6b7e95ac49d753f19cab5a825dea99a1149a04e4e3230b33ae16e120954c04"
"checksum async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423"
"checksum async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf6039b315300e057d198b9d3ab92ee029e31c759b7f1afae538145e6f18a3e"
"checksum async-task 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "698d676dbe689c72ebd57de09e7eb0db9f38fd8dd0cf6c5dc8d76971ebecde1b"
"checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c"
diff --git a/netmod-mem/Cargo.toml b/netmod-mem/Cargo.toml
index c53e4dc..1d494ed 100644
--- a/netmod-mem/Cargo.toml
+++ b/netmod-mem/Cargo.toml
@@ -9,3 +9,8 @@ license = "AGPL-3.0"
[dependencies]
ratman-netmod = { path = "../ratman/netmod", package = "ratman-netmod" }
ratman-identity = { path = "../ratman/identity", package = "ratman-identity", features = [ "digest" ] }
async-trait = "0.1"

[dependencies.async-std]
version = "1"
features = ["attributes"]
diff --git a/netmod-mem/src/lib.rs b/netmod-mem/src/lib.rs
index bf206a0..989fbc9 100644
--- a/netmod-mem/src/lib.rs
+++ b/netmod-mem/src/lib.rs
@@ -3,6 +3,9 @@
//! This aims to make testing any structure that binds against
//! `netmod` easier and reproducable.

use async_std::future;
use async_std::task::Poll;
use async_trait::async_trait;
use ratman_netmod::{Endpoint, Error as NetError, Frame, Result as NetResult};
use std::sync::mpsc::TryRecvError;

@@ -25,9 +28,7 @@ pub struct MemMod {
impl MemMod {
    /// Create a new, unpaired `MemMod`.
    pub fn new() -> Self {
        Self {
            io: None
        }
        Self { io: None }
    }

    /// Create two already-paired `MemMod`s, ready for use.
@@ -76,6 +77,7 @@ impl MemMod {
    }
}

#[async_trait]
impl Endpoint for MemMod {
    /// Provides maximum frame-size information to `RATMAN`
    fn size_hint(&self) -> usize {
@@ -88,7 +90,7 @@ impl Endpoint for MemMod {
    ///
    /// Returns `OperationNotSupported` if attempting to send through
    /// a connection that is not yet connected.
    fn send(&mut self, frame: Frame, _: i16) -> NetResult<()> {
    async fn send(&mut self, frame: Frame, _: i16) -> NetResult<()> {
        match self.io {
            None => Err(NetError::NotSupported),
            Some(ref io) => match io.out.send(frame) {
@@ -98,27 +100,15 @@ impl Endpoint for MemMod {
        }
    }

    fn poll(&mut self) -> NetResult<Option<(Frame, i16)>> {
        match self.io {
            None => Err(NetError::NotSupported),
    async fn next(&mut self) -> NetResult<(Frame, i16)> {
        future::poll_fn(|_| match self.io {
            None => Poll::Ready(Err(NetError::NotSupported)),
            Some(ref mut io) => match io.inc.try_recv() {
                Ok(v) => {
                    dbg!("Endoint delivery END");
                    Ok(Some((v, 0)))
                },
                Err(TryRecvError::Empty) => Ok(None),
                Err(_) => Err(NetError::ConnectionLost),
                Ok(v) => Poll::Ready(Ok((v, 0))),
                Err(TryRecvError::Empty) => Poll::Pending,
                Err(_) => Poll::Ready(Err(NetError::ConnectionLost)),
            },
        }
    }

    fn listen(&mut self, mut handler: Box<dyn FnMut(Frame, i16) -> NetResult<()>>) -> NetResult<()> {
        match self.io {
            None => Err(NetError::NotSupported),
            Some(ref mut io) => match io.inc.recv() {
                Ok(v) => handler(v, 0),
                Err(_) => return Err(NetError::ConnectionLost),
            },
        }
        })
        .await
    }
}
diff --git a/netmod-mem/src/media.rs b/netmod-mem/src/media.rs
index 8bd5583..a5bded3 100644
--- a/netmod-mem/src/media.rs
+++ b/netmod-mem/src/media.rs
@@ -3,4 +3,3 @@ pub(crate) use tagged_frame::TaggedFrame;

mod broadcast_medium;
pub use broadcast_medium::BroadcastMedium;

diff --git a/netmod-mem/src/media/broadcast_medium.rs b/netmod-mem/src/media/broadcast_medium.rs
index 3e632cc..15366d6 100644
--- a/netmod-mem/src/media/broadcast_medium.rs
+++ b/netmod-mem/src/media/broadcast_medium.rs
@@ -53,15 +53,16 @@ impl BroadcastMedium {
    /// ```
    /// # use netmod_mem::media::BroadcastMedium;
    /// # use ratman_netmod::{Frame, Endpoint};
    /// # #[async_std::main]
    /// # async fn main() {
    /// let mut medium = BroadcastMedium::with_latency(1);
    /// let mut a = medium.make_netmod();
    /// a.send(Frame::dummy(), 0).expect("Couldn't send frame from a.");
    /// a.send(Frame::dummy(), 0).await.expect("Couldn't send frame from a.");
    ///
    /// let mut b = medium.make_netmod();
    /// medium.tick();
    /// b.poll()
    ///     .expect("Failed to get message at b. Error")
    ///     .expect("No messages available to b.");
    /// b.next().await.expect("Failed to get message at b. Error");
    /// # }
    /// ```
    pub fn make_netmod(&mut self) -> impl Endpoint {
        let mut mm = MemMod::new();
diff --git a/netmod-mem/tests/basic.rs b/netmod-mem/tests/basic.rs
index c24718d..74ebf84 100644
--- a/netmod-mem/tests/basic.rs
+++ b/netmod-mem/tests/basic.rs
@@ -1,31 +1,30 @@
use netmod_mem::MemMod;
use ratman_netmod::{Endpoint, Frame};
#[test]
fn ping_pong() {
use async_std;
#[async_std::test]
async fn ping_pong() {
    let mut a = MemMod::new();
    let mut b = MemMod::new();
    a.link(&mut b);
    a.send(Frame::dummy(), 0)
    a.send(Frame::dummy(), 0).await
        .expect("Failed to send message from a. Error");
    b.poll()
        .expect("Failed to get message at b. Error")
        .expect("No message available.");
    b.send(Frame::dummy(), 0)
    b.next().await
        .expect("Failed to get message at b. Error");
    b.send(Frame::dummy(), 0).await
        .expect("Failed to send message from b. Error");
    a.poll()
        .expect("Failed to get message at a. Error")
        .expect("No message available.");
    a.next().await
        .expect("Failed to get message at a. Error");
}

#[test]
fn split() {
#[async_std::test]
async fn split() {
    let mut a = MemMod::new();
    let mut b = MemMod::new();
    a.link(&mut b);
    a.send(Frame::dummy(), 0)
    a.send(Frame::dummy(), 0).await
        .expect("Failed to send message from a. Error");
    // Disconnect the two interfaces, so the message sent by A will never be
    // received by B.
    b.split();
    assert!(b.poll().is_err());
    assert!(b.next().await.is_err());
}
diff --git a/netmod-mem/tests/broadcast.rs b/netmod-mem/tests/broadcast.rs
index 4be8896..ccce0c2 100644
--- a/netmod-mem/tests/broadcast.rs
+++ b/netmod-mem/tests/broadcast.rs
@@ -1,41 +1,39 @@
use netmod_mem::media::BroadcastMedium;
use ratman_netmod::{Endpoint, Frame};
#[test]
fn broadcast_medium_ping_pong() {
use async_std;

#[async_std::test]
async fn broadcast_medium_ping_pong() {
    let mut medium = BroadcastMedium::with_latency(1);
    let mut a = medium.make_netmod();
    let mut b = medium.make_netmod();
    a.send(Frame::dummy(), 0)
    a.send(Frame::dummy(), 0).await
        .expect("Failed to send message from a. Error");
    medium.tick();
    b.poll()
        .expect("Failed to get message at b. Error")
        .expect("No message available.");
    b.send(Frame::dummy(), 0)
    b.next().await
        .expect("Failed to get message at b. Error");
    b.send(Frame::dummy(), 0).await
        .expect("Failed to send message from b. Error");
    medium.tick();
    a.poll()
        .expect("Failed to get message at a. Error")
        .expect("No message available.");
    a.next().await
        .expect("Failed to get message at a. Error");
}

#[test]
fn broadcast_medium_ping_broadcast() {
#[async_std::test]
async fn broadcast_medium_ping_broadcast() {
    let mut medium = BroadcastMedium::with_latency(1);
    let mut a = medium.make_netmod();
    let mut b = medium.make_netmod();
    let mut c = medium.make_netmod();
    let mut d = medium.make_netmod();
    a.send(Frame::dummy(), 0)

    a.send(Frame::dummy(), 0).await
        .expect("Failed to send message from a. Error");
    medium.tick();
    b.poll()
        .expect("Failed to get message at b. Error")
        .expect("No message available.");
    c.poll()
        .expect("Failed to get message at c. Error")
        .expect("No message available.");
    d.poll()
        .expect("Failed to get message at d. Error")
        .expect("No message available.");
    b.next().await
        .expect("Failed to get message at b. Error");
    c.next().await
        .expect("Failed to get message at c. Error");
    d.next().await
        .expect("Failed to get message at d. Error");
}
-- 
2.24.0

[PATCH 3/3] netmod: first implementation of a blocking netmod::ffi interface Export this patch

---
 Cargo.lock                |  1 +
 ratman/netmod/Cargo.toml  |  2 ++
 ratman/netmod/src/capi.rs | 43 +++++++++++++++++++++++++++++++++++++++
 ratman/netmod/src/lib.rs  | 15 +++++++-------
 4 files changed, 53 insertions(+), 8 deletions(-)
 create mode 100644 ratman/netmod/src/capi.rs

diff --git a/Cargo.lock b/Cargo.lock
index 29b7658..c983ea2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -951,6 +951,7 @@ dependencies = [
name = "ratman-netmod"
version = "0.1.0"
dependencies = [
 "async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
 "conjoiner-engine 1.2.4-alpha.0 (git+https://git.open-communication.net/qaul/conjoiner-engine)",
 "ratman-identity 0.1.0",
diff --git a/ratman/netmod/Cargo.toml b/ratman/netmod/Cargo.toml
index 4ca5413..7afbe36 100644
--- a/ratman/netmod/Cargo.toml
+++ b/ratman/netmod/Cargo.toml
@@ -14,4 +14,6 @@ identity = { path = "../identity", features = ["digest"], package = "ratman-iden
conjoiner = { git = "https://git.open-communication.net/qaul/conjoiner-engine", package = "conjoiner-engine" }
serde = { version = "1.0", features = ["derive"] }
twox-hash = "1.5"

async-trait = "0.1"
async-std = { version = "1.0" }
diff --git a/ratman/netmod/src/capi.rs b/ratman/netmod/src/capi.rs
new file mode 100644
index 0000000..5ae54ec
--- /dev/null
+++ b/ratman/netmod/src/capi.rs
@@ -0,0 +1,43 @@
//! The native platform ABI wrapper for netmod
//!
//! This API is designed to create a coherent interface to write
//! netmod drivers in languages that are not Rust, via the C ABI.

use crate::{Endpoint as EndpointExt, Frame, Result};
use async_std::task;
use async_trait::async_trait;

/// A zero sized type to hold type info for native interface bridge
#[repr(C)]
pub struct Endpoint;

extern "C" {

    /// Let's the native driver provide a size hint for frame delivery
    #[no_mangle]
    pub fn size_hint() -> usize;

    /// Dispatch a Frame through this interface
    #[no_mangle]
    pub fn send(frame: Frame, target: i16);

    /// Get the next available frame from the interface driver
    #[no_mangle]
    pub fn next() -> (Frame, i16);
}

#[async_trait]
impl EndpointExt for Endpoint {
    fn size_hint(&self) -> usize {
        unsafe { size_hint() }
    }

    async fn send(&mut self, frame: Frame, target: i16) -> Result<()> {
        task::block_on(async { unsafe { send(frame, target) } });
        Ok(())
    }

    async fn next(&mut self) -> Result<(Frame, i16)> {
        Ok(task::block_on(async { unsafe { next() } }))
    }
}
diff --git a/ratman/netmod/src/lib.rs b/ratman/netmod/src/lib.rs
index 0a1317a..192c140 100644
--- a/ratman/netmod/src/lib.rs
+++ b/ratman/netmod/src/lib.rs
@@ -1,12 +1,11 @@
//! `netmod` is a network module abstraction for `RATMAN`
//!
//! It provides a small interface to interact with endpoints
//! (send/ receive frames) and basic data frame definitions.
//! It provides a small interface to interact with endpoints (send/
//! receive frames) and basic data frame definitions.
//!
//! The interface itself makes no assumption about underlying
//! address spacing or resend behaviour.
//! Using `netmod` as a library allows you to write
//! RATMAN-compatible network adapters.
//! The interface itself makes no assumption about underlying address
//! spacing or resend behaviour.  Using `netmod` as a library allows
//! you to write RATMAN-compatible network adapters.
//!
//! ## Frames, Sequences and Signatures
//!
@@ -48,12 +47,12 @@
mod endpoint;
mod frame;
mod seq;
// mod payload;
mod result;

pub mod capi;

pub use endpoint::Endpoint;
pub use frame::{Frame, Recipient};
pub use seq::{SeqId, Sequence};

// pub use payload::Payload;
pub use result::{Error, Result};
-- 
2.24.0
View this thread in the archives