Skip to content

Commit

Permalink
Add support for container messages. (#1822)
Browse files Browse the repository at this point in the history
Co-authored-by: Kasper Lund <[email protected]>
  • Loading branch information
floitsch and kasperl authored Sep 26, 2023
1 parent 7c0bade commit 9bcd490
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 11 deletions.
6 changes: 6 additions & 0 deletions lib/system/api/containers.toit
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ interface ContainerService:
image-writer-commit handle/int flags/int data/int -> uuid.Uuid
static IMAGE-WRITER-COMMIT-INDEX /int ::= 5

notify-background-state-changed new-state/any -> none
static NOTIFY-BACKGROUND-STATE-CHANGED-INDEX /int ::= 8

class ContainerServiceClient extends ServiceClient implements ContainerService:
static SELECTOR ::= ContainerService.SELECTOR
constructor selector/ServiceSelector=SELECTOR:
Expand Down Expand Up @@ -75,3 +78,6 @@ class ContainerServiceClient extends ServiceClient implements ContainerService:

image-writer-commit handle/int flags/int data/int -> uuid.Uuid:
return uuid.Uuid (invoke_ ContainerService.IMAGE-WRITER-COMMIT-INDEX [handle, flags, data])

notify-background-state-changed new-state/bool -> none:
invoke_ ContainerService.NOTIFY-BACKGROUND-STATE-CHANGED-INDEX new-state
39 changes: 31 additions & 8 deletions lib/system/containers.toit
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ start id/uuid.Uuid arguments/any=[] -> Container:
uninstall id/uuid.Uuid -> none:
_client_.uninstall-image id

/** Notifies the system about a background-state change. */
notify-background-state-changed new-state/bool -> none:
_client_.notify-background-state-changed new-state

class ContainerImage:
id/uuid.Uuid
name/string?
Expand All @@ -51,6 +55,8 @@ class ContainerImage:
constructor --.id --.name --.flags --.data:

class Container extends ServiceResourceProxy:
static EVENT-BACKGROUND-STATE-CHANGE ::= 0

// TODO(kasper): Rename this and document it.
id/uuid.Uuid

Expand All @@ -70,6 +76,7 @@ class Container extends ServiceResourceProxy:

result_/monitor.Latch ::= monitor.Latch
on-stopped_/Lambda? := null
on-event_/Lambda? := null

constructor.internal_ --handle/int --.id --.gid:
super _client_ handle
Expand Down Expand Up @@ -101,14 +108,30 @@ class Container extends ServiceResourceProxy:
else:
on-stopped_ = lambda

on-notified_ code/int -> none:
result_.set code
on-stopped := on-stopped_
on-stopped_ = null
if on-stopped: on-stopped.call code
// We no longer expect or care about notifications, so
// close the resource.
close
on-event lambda/Lambda? -> none:
if not lambda:
on-event_ = null
return
if on-event_: throw "ALREADY_IN_USE"
on-event_ = lambda

on-notified_ notification/any -> none:
if notification is int:
code/int := notification
result_.set code
on-stopped := on-stopped_
on-stopped_ = null
if on-stopped: on-stopped.call code
// We no longer expect or care about notifications, so
// close the resource.
close
else if on-event_:
if notification is not List or notification.size != 2 or notification[0] is not int:
// Discard unknown event.
return
event-kind := notification[0]
event-value := notification[1]
on-event_.call event-kind event-value

class ContainerImageWriter extends ServiceResourceProxy:
size/int ::= ?
Expand Down
26 changes: 24 additions & 2 deletions system/containers.toit
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import encoding.tison
import system.assets
import system.services show ServiceHandler ServiceProvider ServiceResource
import system.api.containers show ContainerService
import system.containers as system-containers

import .flash.allocation
import .flash.image-writer
Expand All @@ -45,8 +46,7 @@ class Container:

start arguments/any=image.default-arguments -> none:
if pids_: throw "Already started"
pids_ = {}
pids_.add (image.spawn this arguments)
pids_ = {image.spawn this arguments}

stop -> none:
if not pids_: throw "Not started"
Expand All @@ -56,6 +56,11 @@ class Container:
image.manager.on-container-stop_ this 0
resources.do: it.on-container-stop 0

send-event event/any:
if not pids_: throw "Not started"
if pids_.is-empty: return
resources.do: it.send-event event

on-stop_ -> none:
pids_.do: on-process-stop_ it 0

Expand Down Expand Up @@ -91,6 +96,10 @@ class ContainerResource extends ServiceResource:
if is-closed: return
notify_ code

send-event event/List -> none:
if is-closed: return
notify_ event

on-closed -> none:
container.resources.remove this

Expand Down Expand Up @@ -177,6 +186,7 @@ class ContainerImageFlash extends ContainerImage:

abstract class ContainerServiceProvider extends ServiceProvider
implements ContainerService ServiceHandler:

constructor:
super "system/containers" --major=0 --minor=2
provides ContainerService.SELECTOR --handler=this
Expand All @@ -203,12 +213,17 @@ abstract class ContainerServiceProvider extends ServiceProvider
if index == ContainerService.IMAGE-WRITER-COMMIT-INDEX:
writer ::= (resource client arguments[0]) as ContainerImageWriter
return (image-writer-commit writer arguments[1] arguments[2]).to-byte-array
if index == ContainerService.NOTIFY-BACKGROUND-STATE-CHANGED-INDEX:
return send-container-event --gid=gid
system-containers.Container.EVENT-BACKGROUND-STATE-CHANGE
arguments
unreachable

abstract image-registry -> FlashRegistry
abstract images -> List
abstract add-flash-image allocation/FlashAllocation -> ContainerImage
abstract lookup-image id/uuid.Uuid -> ContainerImage?
abstract send-container-event --gid/int event-kind/int event-value/any -> none

list-images -> List:
names := {:}
Expand Down Expand Up @@ -263,6 +278,9 @@ abstract class ContainerServiceProvider extends ServiceProvider
image := add-flash-image allocation
return image.id

notify-background-state-changed new-state/bool:
unreachable // Here to satisfy the checker.
class ContainerManager extends ContainerServiceProvider implements SystemMessageHandler_:
image-registry/FlashRegistry ::= ?
service-manager_/SystemServiceManager ::= ?
Expand Down Expand Up @@ -366,6 +384,10 @@ class ContainerManager extends ContainerServiceProvider implements SystemMessage
else:
unreachable

send-container-event --gid/int event-kind/int event-value/any -> none:
container/Container? := lookup-container gid
if container: container.send-event [event-kind, event-value]

trace-using-print message/ByteArray --from=0 --to=message.size:
// Print a trace message on output so that that you can easily decode.
// The message is base64 encoded to limit the output size.
Expand Down
16 changes: 16 additions & 0 deletions tests/containers-test.toit
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the tests/LICENSE file.
import monitor
import system.containers
import expect show *

Expand All @@ -15,6 +16,7 @@ main arguments:

test-images
test-start
test-background-state-changed

test-images:
images/List := containers.images
Expand Down Expand Up @@ -58,5 +60,19 @@ test-start:
expect-equals 0 lambda4-value
expect-equals 0 sub4.wait

test-background-state-changed:
sub := containers.start containers.current { "background-state-test": true }
channel := monitor.Channel 1
sub.on-event:: | event-id/int value |
expect-equals containers.Container.EVENT-BACKGROUND-STATE-CHANGE event-id
channel.send value

expect_equals true channel.receive
expect_equals false channel.receive

main-child arguments/Map:
if arguments.contains "background-state-test":
sleep --ms=10
containers.notify-background-state-changed true
containers.notify-background-state-changed false
sleep --ms=100
2 changes: 1 addition & 1 deletion tests/negative/gold/illegal-system-call-test.gold
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
As check failed: null is not a ServiceResource.
0: ServiceProvider.resource <sdk>/system/services.toit:401:5
1: ContainerServiceProvider.handle <...>/system/containers.toit:201:19
1: ContainerServiceProvider.handle <...>/system/containers.toit:211:19
2: ServiceManager_.<lambda> <sdk>/system/services.toit:634:15
3: RpcRequest_.process.<block> <sdk>/rpc/broker.toit:98:26
4: RpcRequest_.process <sdk>/rpc/broker.toit:95:3
Expand Down

0 comments on commit 9bcd490

Please sign in to comment.