Skip to content

Commit

Permalink
Support multiple providers for the same service (#1393)
Browse files Browse the repository at this point in the history
* Work in progress

* More work

* Better comments

* Refactor

* Update gold

* Add service priorities

* Allow multiple handlers per service provider

* Start extending new test case

* Implement hacky disambiguation

* Update gold

* Add disambiguation filter

* More filtering options

* Introduce service selectors

* Minor cleanups

* Apply suggestions from code review

Co-authored-by: Florian Loitsch <[email protected]>

* Introduce more selectors

* Use WifiService.SELECTOR

* Allow unknown root cert for wong.host.badssl.com

* Cleanups

* Improve service network test using tags

* Fix health

---------

Co-authored-by: Florian Loitsch <[email protected]>
  • Loading branch information
kasperl and floitsch authored Feb 3, 2023
1 parent 311706a commit 02f79fa
Show file tree
Hide file tree
Showing 51 changed files with 1,036 additions and 406 deletions.
26 changes: 14 additions & 12 deletions examples/service.toit
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,45 @@ import system.services
main:
spawn::
service := LogServiceDefinition
service := LogServiceProvider
service.install
service.uninstall --wait // Wait until last client closes.
logger := LogServiceClient
logger.open
logger.log "Hello"
logger.log "World"
logger.close

// ------------------------------------------------------------------
interface LogService:
static UUID/string ::= "00e1aca5-4861-4ec6-86e6-eea82936af13"
static MAJOR/int ::= 1
static MINOR/int ::= 0
static SELECTOR ::= services.ServiceSelector
--uuid="00e1aca5-4861-4ec6-86e6-eea82936af13"
--major=1
--minor=0

static LOG_INDEX ::= 0
log message/string -> none
static LOG_INDEX ::= 0

// ------------------------------------------------------------------
class LogServiceClient extends services.ServiceClient implements LogService:
constructor --open/bool=true:
super --open=open

open -> LogServiceClient?:
return (open_ LogService.UUID LogService.MAJOR LogService.MINOR) and this
static SELECTOR ::= LogService.SELECTOR
constructor selector/services.ServiceSelector=SELECTOR:
assert: selector.matches SELECTOR
super selector

log message/string -> none:
invoke_ LogService.LOG_INDEX message

// ------------------------------------------------------------------
class LogServiceDefinition extends services.ServiceDefinition implements LogService:
class LogServiceProvider extends services.ServiceProvider
implements LogService services.ServiceHandler:
constructor:
super "log" --major=1 --minor=0
provides LogService.UUID LogService.MAJOR LogService.MINOR
provides LogService.SELECTOR --handler=this

handle pid/int client/int index/int arguments/any -> any:
if index == LogService.LOG_INDEX: return log arguments
Expand Down
10 changes: 5 additions & 5 deletions lib/core/message_.toit
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ SYSTEM_SPAWNED_ ::= 1
SYSTEM_TRACE_ ::= 2 // Stack traces, histograms, and profiling information.
// System message types for service RPCs.
SYSTEM_RPC_REQUEST_ ::= 3
SYSTEM_RPC_REPLY_ ::= 4
SYSTEM_RPC_CANCEL_ ::= 5
SYSTEM_RPC_NOTIFY_ ::= 6
SYSTEM_RPC_NOTIFY_RESOURCE_ ::= 7
SYSTEM_RPC_REQUEST_ ::= 3
SYSTEM_RPC_REPLY_ ::= 4
SYSTEM_RPC_CANCEL_ ::= 5
SYSTEM_RPC_NOTIFY_TERMINATED_ ::= 6
SYSTEM_RPC_NOTIFY_RESOURCE_ ::= 7

/**
Sends the $message with $type to the process identified by $pid.
Expand Down
4 changes: 2 additions & 2 deletions lib/core/print.toit
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ write_on_stderr_ message/string add_newline/bool -> none:
/**
Print service used by $print.
*/
service_/PrintService ::= (PrintServiceClient --no-open).open or
StandardPrintService_
service_/PrintService ::= (PrintServiceClient).open
--if_absent=: StandardPrintService_

/**
Standard print service used when the system print service cannot
Expand Down
4 changes: 2 additions & 2 deletions lib/log/target.toit
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class DefaultTarget implements Target:
/**
Log service used by $DefaultTarget.
*/
service_/LogService ::= (LogServiceClient --no-open).open or
StandardLogService_
service_/LogService ::= (LogServiceClient).open
--if_absent=: StandardLogService_

/**
Standard log service used when the system log service cannot
Expand Down
3 changes: 2 additions & 1 deletion lib/net/cellular.toit
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ CONFIG_OPEN_DRAIN /int ::= 2
CONFIG_PRIORITY_LOW /int ::= 0
CONFIG_PRIORITY_HIGH /int ::= 1

service_/CellularServiceClient? ::= (CellularServiceClient --no-open).open
service_/CellularServiceClient? ::= (CellularServiceClient).open
--if_absent=: null

open config/Map? -> net.Interface:
service := service_
Expand Down
3 changes: 2 additions & 1 deletion lib/net/impl.toit
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import .modules.udp
import system.api.network show NetworkService NetworkServiceClient
import system.base.network show NetworkResourceProxy

service_/NetworkServiceClient? ::= (NetworkServiceClient --no-open).open
service_/NetworkServiceClient? ::= (NetworkServiceClient).open
--if_absent=: null

open -> net.Interface:
service := service_
Expand Down
3 changes: 2 additions & 1 deletion lib/net/wifi.toit
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ WIFI_SCAN_ELEMENT_COUNT_ ::= 5

SCAN_TIMEOUT_MS_/int := 1000

service_/WifiServiceClient? ::= (WifiServiceClient --no-open).open
service_/WifiServiceClient? ::= (WifiServiceClient).open
--if_absent=: null

class AccessPoint:
ssid/string
Expand Down
19 changes: 10 additions & 9 deletions lib/system/api/cellular.toit
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@
// found in the lib/LICENSE file.
import system.api.network show NetworkService NetworkServiceClient
import system.services show ServiceSelector

interface CellularService extends NetworkService:
static UUID /string ::= "83798564-d965-49bf-b69d-7f05a082f4f0"
static MAJOR /int ::= 0
static MINOR /int ::= 2
static SELECTOR ::= ServiceSelector
--uuid="83798564-d965-49bf-b69d-7f05a082f4f0"
--major=0
--minor=2

static CONNECT_INDEX /int ::= 1000
connect config/Map? -> List
static CONNECT_INDEX /int ::= 1000

class CellularServiceClient extends NetworkServiceClient implements CellularService:
constructor --open/bool=true:
super --open=open

open -> CellularServiceClient?:
return (open_ CellularService.UUID CellularService.MAJOR CellularService.MINOR) and this
static SELECTOR ::= CellularService.SELECTOR
constructor selector/ServiceSelector=SELECTOR:
assert: selector.matches SELECTOR
super selector

connect config/Map? -> List:
return invoke_ CellularService.CONNECT_INDEX config
18 changes: 9 additions & 9 deletions lib/system/api/containers.toit
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
// found in the lib/LICENSE file.
import uuid
import system.services show ServiceClient
import system.services show ServiceSelector ServiceClient
import system.containers show ContainerImage

interface ContainerService:
static UUID /string ::= "358ee529-45a4-409e-8fab-7a28f71e5c51"
static MAJOR /int ::= 0
static MINOR /int ::= 6
static SELECTOR ::= ServiceSelector
--uuid="358ee529-45a4-409e-8fab-7a28f71e5c51"
--major=0
--minor=6

static FLAG_RUN_BOOT /int ::= 1 << 0
static FLAG_RUN_CRITICAL /int ::= 1 << 1
Expand Down Expand Up @@ -39,11 +40,10 @@ interface ContainerService:
static IMAGE_WRITER_COMMIT_INDEX /int ::= 5

class ContainerServiceClient extends ServiceClient implements ContainerService:
constructor --open/bool=true:
super --open=open

open -> ContainerServiceClient?:
return (open_ ContainerService.UUID ContainerService.MAJOR ContainerService.MINOR) and this
static SELECTOR ::= ContainerService.SELECTOR
constructor selector/ServiceSelector=SELECTOR:
assert: selector.matches SELECTOR
super selector

list_images -> List:
array := invoke_ ContainerService.LIST_IMAGES_INDEX null
Expand Down
18 changes: 9 additions & 9 deletions lib/system/api/firmware.toit
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
// Use of this source code is governed by an MIT-style license that can be
// found in the lib/LICENSE file.
import system.services show ServiceClient
import system.services show ServiceSelector ServiceClient

interface FirmwareService:
static UUID /string ::= "777096e8-05bc-4af7-919e-5ba696549bd5"
static MAJOR /int ::= 0
static MINOR /int ::= 5
static SELECTOR ::= ServiceSelector
--uuid="777096e8-05bc-4af7-919e-5ba696549bd5"
--major=0
--minor=5

is_validation_pending -> bool
static IS_VALIDATION_PENDING_INDEX /int ::= 0
Expand Down Expand Up @@ -49,11 +50,10 @@ interface FirmwareService:
static FIRMWARE_WRITER_COMMIT_INDEX /int ::= 7

class FirmwareServiceClient extends ServiceClient implements FirmwareService:
constructor --open/bool=true:
super --open=open

open -> FirmwareServiceClient?:
return (open_ FirmwareService.UUID FirmwareService.MAJOR FirmwareService.MINOR) and this
static SELECTOR ::= FirmwareService.SELECTOR
constructor selector/ServiceSelector=SELECTOR:
assert: selector.matches SELECTOR
super selector

is_validation_pending -> bool:
return invoke_ FirmwareService.IS_VALIDATION_PENDING_INDEX null
Expand Down
20 changes: 10 additions & 10 deletions lib/system/api/log.toit
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
// Use of this source code is governed by an MIT-style license that can be
// found in the lib/LICENSE file.
import system.services show ServiceClient
import system.services show ServiceSelector ServiceClient

interface LogService:
static UUID /string ::= "89e6340c-67f5-4055-b1d1-b4f4c2755f67"
static MAJOR /int ::= 0
static MINOR /int ::= 1
static SELECTOR ::= ServiceSelector
--uuid="89e6340c-67f5-4055-b1d1-b4f4c2755f67"
--major=0
--minor=1

static LOG_INDEX /int ::= 0
log level/int message/string names/List? keys/List? values/List? -> none
static LOG_INDEX /int ::= 0

class LogServiceClient extends ServiceClient implements LogService:
constructor --open/bool=true:
super --open=open

open -> LogServiceClient?:
return (open_ LogService.UUID LogService.MAJOR LogService.MINOR) and this
static SELECTOR ::= LogService.SELECTOR
constructor selector/ServiceSelector=SELECTOR:
assert: selector.matches SELECTOR
super selector

log level/int message/string names/List? keys/List? values/List? -> none:
invoke_ LogService.LOG_INDEX [level, message, names, keys, values]
54 changes: 27 additions & 27 deletions lib/system/api/network.toit
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import net
import net.udp
import net.tcp

import system.services show ServiceClient
import system.services show ServiceSelector ServiceClient

// For references in documentation comments.
import system.services show ServiceResource ServiceResourceProxy

interface NetworkService:
static UUID /string ::= "063e228a-3a7a-44a8-b024-d55127255ccb"
static MAJOR /int ::= 0
static MINOR /int ::= 3
static SELECTOR ::= ServiceSelector
--uuid="063e228a-3a7a-44a8-b024-d55127255ccb"
--major=0
--minor=3

/**
Proxy mask bits that indicate which operations must be proxied
Expand Down Expand Up @@ -43,66 +44,65 @@ interface NetworkService:
// the proxy mask bits in a list. The proxy mask bits indicate
// which operations the service definition wants the client to
// proxy through it.
static CONNECT_INDEX /int ::= 0
connect -> List
static CONNECT_INDEX /int ::= 0

static ADDRESS_INDEX /int ::= 1
address handle/int -> ByteArray
static ADDRESS_INDEX /int ::= 1

static RESOLVE_INDEX /int ::= 2
resolve handle/int host/string -> List
static RESOLVE_INDEX /int ::= 2

static UDP_OPEN_INDEX /int ::= 100
udp_open handle/int port/int? -> int
static UDP_OPEN_INDEX /int ::= 100

static UDP_CONNECT_INDEX /int ::= 101
udp_connect handle/int ip/ByteArray port/int -> none
static UDP_CONNECT_INDEX /int ::= 101

static UDP_RECEIVE_INDEX /int ::= 102
udp_receive handle/int -> List
static UDP_RECEIVE_INDEX /int ::= 102

static UDP_SEND_INDEX /int ::= 103
udp_send handle/int data/ByteArray ip/ByteArray port/int -> none
static UDP_SEND_INDEX /int ::= 103

static TCP_CONNECT_INDEX /int ::= 200
tcp_connect handle/int ip/ByteArray port/int -> int
static TCP_CONNECT_INDEX /int ::= 200

static TCP_LISTEN_INDEX /int ::= 201
tcp_listen handle/int port/int -> int
static TCP_LISTEN_INDEX /int ::= 201

static TCP_ACCEPT_INDEX /int ::= 202
tcp_accept handle/int -> int
static TCP_ACCEPT_INDEX /int ::= 202

static TCP_CLOSE_WRITE_INDEX /int ::= 203
tcp_close_write handle/int -> none
static TCP_CLOSE_WRITE_INDEX /int ::= 203

static SOCKET_GET_OPTION_INDEX /int ::= 300
socket_get_option handle/int option/int -> any
static SOCKET_GET_OPTION_INDEX /int ::= 300

static SOCKET_SET_OPTION_INDEX /int ::= 301
socket_set_option handle/int option/int value/any -> none
static SOCKET_SET_OPTION_INDEX /int ::= 301

static SOCKET_LOCAL_ADDRESS_INDEX /int ::= 302
socket_local_address handle/int -> List
static SOCKET_LOCAL_ADDRESS_INDEX /int ::= 302

static SOCKET_PEER_ADDRESS_INDEX /int ::= 303
socket_peer_address handle/int -> List
static SOCKET_PEER_ADDRESS_INDEX /int ::= 303

static SOCKET_READ_INDEX /int ::= 304
socket_read handle/int -> ByteArray?
static SOCKET_READ_INDEX /int ::= 304

static SOCKET_WRITE_INDEX /int ::= 305
socket_write handle/int data -> int
static SOCKET_WRITE_INDEX /int ::= 305

static SOCKET_MTU_INDEX /int ::= 306
socket_mtu handle/int -> int
static SOCKET_MTU_INDEX /int ::= 306

class NetworkServiceClient extends ServiceClient implements NetworkService:
constructor --open/bool=true:
super --open=open

open -> NetworkServiceClient?:
return (open_ NetworkService.UUID NetworkService.MAJOR NetworkService.MINOR) and this
static SELECTOR ::= NetworkService.SELECTOR
constructor selector/ServiceSelector=SELECTOR:
assert: selector.matches SELECTOR
super selector

connect -> List:
return invoke_ NetworkService.CONNECT_INDEX null
Expand Down
Loading

0 comments on commit 02f79fa

Please sign in to comment.