doc
This commit is contained in:
parent
ac18f967ec
commit
eac6052df4
1 changed files with 36 additions and 18 deletions
54
doc/pods.md
54
doc/pods.md
|
|
@ -36,19 +36,18 @@ Eductional examples of pods can be found [here](examples/pods):
|
||||||
database. Implemented in Python.
|
database. Implemented in Python.
|
||||||
|
|
||||||
- [pod-babashka-filewatcher](examples/pods/pod-babashka-filewatcher): a
|
- [pod-babashka-filewatcher](examples/pods/pod-babashka-filewatcher): a
|
||||||
filewatcher pod. It exposes one function `pod-babashka-filewatcher/watch` and
|
filewatcher pod. Implemented in Rust.
|
||||||
return a `core.async` channel to listen for change events for a file
|
|
||||||
path. Implemented in Rust.
|
|
||||||
|
|
||||||
### Naming
|
### Naming
|
||||||
|
|
||||||
When choosing a name for your pod, considering the following naming scheme:
|
When choosing a name for your pod, we suggest the following naming scheme:
|
||||||
|
|
||||||
```
|
```
|
||||||
pod-<user-id>-<pod-name>
|
pod-<user-id>-<pod-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
where `<user-id>` is your Github, Gitlab, etc. handle and `<pod-name>` describes the intent of your pod.
|
where `<user-id>` is your Github or Gitlab handle and `<pod-name>` describes
|
||||||
|
what your pod is about.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
|
@ -84,11 +83,14 @@ Bencode is chosen as the message format because it is a light-weight format
|
||||||
which can be implemented in 200-300 lines of code in most languages. If pods are
|
which can be implemented in 200-300 lines of code in most languages. If pods are
|
||||||
implemented in Clojure, they only need to depend on the
|
implemented in Clojure, they only need to depend on the
|
||||||
[bencode](https://github.com/nrepl/bencode) library and use `pr-str` and
|
[bencode](https://github.com/nrepl/bencode) library and use `pr-str` and
|
||||||
`edn/read-string` for encoding and decoding payloads. Then why not use EDN as
|
`edn/read-string` for encoding and decoding payloads.
|
||||||
the message format? Assuming EDN (or JSON for that matter) as the message and
|
|
||||||
payload format for all pods is too constraining: other languages might already
|
Why isn't EDN or JSON chosen as the message format instead of bencode, you may
|
||||||
have built-in JSON support and there might not be a good EDN library available.
|
ask. Assuming EDN or JSON as the message and payload format for all pods is too
|
||||||
More payload formats might be added in the future (e.g. transit).
|
constraining: other languages might already have built-in JSON support and there
|
||||||
|
might not be a good EDN library available. So we use bencode as the first
|
||||||
|
encoding and choose one of multiple richer encodings on top of this. More
|
||||||
|
payload formats might be added in the future (e.g. transit).
|
||||||
|
|
||||||
When calling the `babashka.pods/load-pod` function, babashka will start the pod
|
When calling the `babashka.pods/load-pod` function, babashka will start the pod
|
||||||
and leave the pod running throughout the duration of a babashka script.
|
and leave the pod running throughout the duration of a babashka script.
|
||||||
|
|
@ -121,20 +123,26 @@ In this reply, the pod declares that payloads will be encoded and decoded using
|
||||||
JSON. It also declares that the pod exposes one namespace,
|
JSON. It also declares that the pod exposes one namespace,
|
||||||
`pod.lispyclouds.sqlite` with one var `execute!`.
|
`pod.lispyclouds.sqlite` with one var `execute!`.
|
||||||
|
|
||||||
|
The pod encodes the above map to bencode and writes it to stdoud. Babashka reads
|
||||||
|
this message from the pod's stdout.
|
||||||
|
|
||||||
Upon receiving this message, babashka creates these namespaces and vars.
|
Upon receiving this message, babashka creates these namespaces and vars.
|
||||||
|
|
||||||
The user can load your pod with:
|
As a babashka user, you can load the pod with:
|
||||||
|
|
||||||
``` clojure
|
``` clojure
|
||||||
(require '[babashka.pods :as pods])
|
(require '[babashka.pods :as pods])
|
||||||
(pods/load-pod "pod-lispyclouds-sqlite")
|
(pods/load-pod "pod-lispyclouds-sqlite")
|
||||||
(some? (find-ns 'pod.lispyclouds.sqlite)) ;;=> true
|
(some? (find-ns 'pod.lispyclouds.sqlite)) ;;=> true
|
||||||
|
;; yay, the namespace exists!
|
||||||
|
|
||||||
|
;; let's give the namespace an alias
|
||||||
(require '[pod.lispyclouds.sqlite :as sql])
|
(require '[pod.lispyclouds.sqlite :as sql])
|
||||||
```
|
```
|
||||||
|
|
||||||
#### invoke
|
#### invoke
|
||||||
|
|
||||||
When invoking var that is related to the pod, let's call it a _proxy var_,
|
When invoking a var that is related to the pod, let's call it a _proxy var_,
|
||||||
babashka reaches out to the pod with the arguments encoded in JSON or EDN. The
|
babashka reaches out to the pod with the arguments encoded in JSON or EDN. The
|
||||||
pod will then respond with a return value encoded in JSON or EDN. Babashka will
|
pod will then respond with a return value encoded in JSON or EDN. Babashka will
|
||||||
then decode the return value and present the user with that.
|
then decode the return value and present the user with that.
|
||||||
|
|
@ -156,12 +164,12 @@ An example response from the pod could look like:
|
||||||
``` clojure
|
``` clojure
|
||||||
{"id" "1d17f8fe-4f70-48bf-b6a9-dc004e52d056"
|
{"id" "1d17f8fe-4f70-48bf-b6a9-dc004e52d056"
|
||||||
"value" "[[1] [2]]"
|
"value" "[[1] [2]]"
|
||||||
"status" "[\"done\"]"
|
"status" "[\"done\"]"}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, the `value` payload is the return value payload. The field `status`
|
Here, the `value` payload is the return value of the function invocation. The
|
||||||
contains `"done"` so babashka knows that this is the last message related to the
|
field `status` contains `"done"`. This tells babashka that this is the last
|
||||||
request with `id` `1d17f8fe-4f70-48bf-b6a9-dc004e52d056`.
|
message related to the request with `id` `1d17f8fe-4f70-48bf-b6a9-dc004e52d056`.
|
||||||
|
|
||||||
Now you know most there is to know about the pod protocol!
|
Now you know most there is to know about the pod protocol!
|
||||||
|
|
||||||
|
|
@ -187,10 +195,20 @@ Responses may contain an `ex-message` string and `ex-data` payload string (JSON
|
||||||
or EDN) along with an `"error"` value in `status`. This will cause babashka to
|
or EDN) along with an `"error"` value in `status`. This will cause babashka to
|
||||||
throw an `ex-info` with the associated values.
|
throw an `ex-info` with the associated values.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
{"id" "1d17f8fe-4f70-48bf-b6a9-dc004e52d056"
|
||||||
|
"ex-message" "Illegal input"
|
||||||
|
"ex-data" "{\"input\": 10}
|
||||||
|
"status" "[\"done\", \"error\"]"}
|
||||||
|
```
|
||||||
|
|
||||||
#### async
|
#### async
|
||||||
|
|
||||||
Pods may implement async functions that return one or more values at any time in
|
Pods may implement async functions that return one or more values at a later
|
||||||
the future. This must be declared as part of the `describe` response:
|
time in the future. Async functions must be declared as such as part of the
|
||||||
|
`describe` response message:
|
||||||
|
|
||||||
``` clojure
|
``` clojure
|
||||||
{"format" "json"
|
{"format" "json"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue