Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add services via thunk addrs #225

Merged
merged 6 commits into from
Aug 8, 2022
Merged

add services via thunk addrs #225

merged 6 commits into from
Aug 8, 2022

Conversation

vito
Copy link
Owner

@vito vito commented Aug 7, 2022

  • thunks now configure a list of named ports that they listen on
  • (addr thunk name format) returns a thunk addr(ess), a new value type

A thunk addr is sort of like a thunk path except it refers to a TCP address of a service run by a thunk rather than a file created by a thunk. It embeds a format string for the address which will be rendered at runtime.

Just like thunk paths, thunk addrs are just data values. The service thunk only runs when it's needed by another thunk.

When a thunk addr is passed to another thunk the runtime will run the embedded service thunk, poll until all ports are live, and then render the format string with an appropriate host and a port reachable by the consumer thunk. The format string uses os.Expand syntax, which is just $foo and ${foo}.

Here's a simple client + server:

(def server
  (from (linux/nixery.dev/simple-http-server)
    (-> ($ simple-http-server)
        (with-port :http 8000))))

(-> ($ curl (addr server :http "http://$host:$port"))
    (with-image (linux/nixery.dev/curl))
    run)

Or, pointlessly:

(run (from (linux/nixery.dev/curl)
       ($ curl (addr (from (linux/nixery.dev/simple-http-server)
                       (with-port ($ simple-http-server) :http 8000))
                     :http
                     "http://$host:$port"))))

See also demos/addrs.bass.

When a thunk completes, Bass "disconnects" from the service thunk, stopping it if it's the last thunk using it. Thanks to Buildkit semantics there will be only ever be one instance of a service thunk running, and its progress will be multiplexed to all clients. It will only be interrupted when all concurrent clients disconnect. This means multiple thunks using the same service will all share the same service as long as at least one of them is running.

With this design you can use services like values without worrying about managing complicated lifecycle across many runs. The service will appear when it's needed and disappear when it's no longer needed.

Currently buildkit does not support container networking (just "host" or "none") so $host will always be localhost or 127.0.0.1, but support for that may arrive someday: moby/buildkit#28

show me!

image

bonus material

nixery

A thunk addr may also be used as a thunk's image repository to run images from a local registry service thunk. See nix.bass for using Nixery.

add (wait), interrupt on exit

By default, scripts now interrupt any background thunks before waiting on exit. This way you can start services in the background if you want to and they'll be automatically cleaned up.

To wait for background thunks instead of interrupting them, use the new (wait) function.

hashes changed from base64 to base32

Thunk hashes have been changed (again - #203) to base32 encoding instead of base64. This is a speculative change so they can be re-used for hostnames in the future. Base32 is still short enough, but it's a bit screamy. Leaving it as-is for now.

refactor image archive out of image ref

Support for OCI image archives was shimmed into the existing image ref type, which felt a little misfit since not all fields were relevant between them. It has been refactored out into a separate ImageArchive.

vito added 4 commits August 7, 2022 12:56
* thunks can now configure named ports
* ThunkAddr is a new Value referencing a port provided by a thunk

ThunkAddr is like ThunkPath but for TCP addresses instead of files. It
embeds a format string to be resolved at runtime. They are constructed
with the (addr) function.

e.g.:

    (addr (with-ports ($ foo) {:http 8080}) :http "http://$host:$port")

When a ThunkAddr is used in a thunk its embedded thunk is started, all
ports are polled until ready, and the value is replaced with the
rendered format string.

    (let [thunk (-> ($ foo) (with-ports {:http 8080}))
          addr (addr thunk :http "http://$host:$port")]
      ($ curl $addr))

(not a working example; images etc. omitted)

Currently buildkit does not support custom networking so $host will
always be localhost, but support may arrive someday.
+ rename thunk image types to not be so heavily prefixed
using a list of objects is much more future-proof

replace (with-ports scope) with (with-port name num)
@vito vito added the enhancement New feature or request label Aug 7, 2022
@vito vito changed the title add thunk addrs add services via thunk addrs Aug 7, 2022
vito added 2 commits August 7, 2022 19:39
this is a neat way we could implement service discovery, but right now
everything just runs on the host network, so there's no point.
localhost should be more portable; I have a vague notion of it being
used for mapping networks to local Linux VMs and such (e.g. WSL), but
don't know that it actually matters yet
@vito vito merged commit c8e6c82 into main Aug 8, 2022
@vito vito deleted the addrs branch August 8, 2022 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant