Fork me on GitHub
#babashka
<
2023-06-22
>
jeroenvandijk11:06:59

Is there an example of a Babashka Pod that streams output back to the client? 🧵

borkdude12:06:25

I think bbssh has such an example

Crispin06:06:01

Yes bbssh streams data. Strap on your asbestos underwear though 😉

Crispin06:06:29

it has some read/write functions in the injected bb pod code that serialise the data to be sent to the pod eg https://github.com/epiccastle/bbssh/blob/main/src/bb/pod/epiccastle/bbssh/output_stream.clj#L28-L45

Crispin06:06:34

and these are wrapped into java stream objects on the bb side using proxy so that other bb code like the process code can use them eg https://github.com/epiccastle/bbssh/blob/main/src/bb/pod/epiccastle/bbssh/output_stream.clj#L60-L75

Crispin06:06:49

In the pod, these are hooked into the read/write methods of the stream objects on the pod side

Crispin06:06:05

the tricky bit is that some of these remote calls will block

Crispin06:06:29

and you don't want to halt the pod message processing mainline. So I used some metadata to annotate these blocking functions so I could handle them specially in the pod message core loop. Here you can see a ^:blocking call. https://github.com/epiccastle/bbssh/blob/main/src/clj/pod/epiccastle/bbssh/pod/byte_array_input_stream.clj#L44-L60

Crispin06:06:08

there is also an ^:async annotation. For data coming back, you want to run things on the pod side, and have it send data back to your bb mainline at some later point. These async annotated functions implement this "callback" situation using bb pod async calls. These are used in the constructors for the pod side stream proxy eg https://github.com/epiccastle/bbssh/blob/main/src/clj/pod/epiccastle/bbssh/pod/input_stream.clj#L65

Crispin06:06:18

and the actual firing of those pod initiated callbacks (sending streaming data from the pod to bb on demand) is handled in this little namespace https://github.com/epiccastle/bbssh/blob/main/src/clj/pod/epiccastle/bbssh/pod/callbacks.clj

Crispin06:06:49

It is fairly tricky, but once all this is in place, streaming works in both directions.

jeroenvandijk07:06:56

Thanks you for this extensive explaination @U1QQJJK89

jeroenvandijk07:06:12

Sounds like it was quite an undertaking to get this working

jeroenvandijk07:06:19

I’ll study what you did, but I think I’ll postpone my idea a bit. So far it was just a nice to have, maybe this will change later

Crispin07:06:32

If you are only streaming in one direction things are a bit more simple.

jeroenvandijk08:06:44

Yeah i was thinking of wrapping another process in a pod, send some commands to it, and then tail the results

Crispin08:06:12

right, you can do that just with async functions in the pod. (This is how streams from the pod to bb are implemented in bbssh) https://github.com/babashka/pods#async

jeroenvandijk08:06:50

Ah cool, might be worth a try. Thanks!