diff --git a/claim.capnp b/claim.capnp index f2c10d4..a642993 100644 --- a/claim.capnp +++ b/claim.capnp @@ -6,21 +6,25 @@ $CSharp.namespace("FabAccessAPI.Schema"); using import "/capnp/rpc.capnp".SturdyRef; using import "persistent.capnp".Persistent; -using import "state.capnp".State; -using import "state.capnp".Update; +using import "resource.capnp".Resource; +using import "notify.capnp".Notifiable; +using import "utils.capnp".Fallible; +using import "utils.capnp".OID; +using import "utils.capnp".Map; interface Claimable { - restore @0 ( sturdy :SturdyRef ) -> ( claim :Claim ); - # Restore a previously saved SturdyRef pointing to a Claim - - claim @1 () -> ( claim :Claim ); + claim @0 () -> Fallible(Claim, ClaimError); # returns NULL if the resource is *currently* not claimable. # drop the returned claim capability to unclaim it. + + interface ClaimError { + + } } interface Lockable { restore @0 ( sturdy :SturdyRef ) -> ( lock :Lock ); - # Restore a previously saved SturdyRef pointing to a Claim + # Restore a previously saved SturdyRef pointing to a Lock lock @1 () -> ( lock :Lock ); # Take exclusive access to a resource, disowning all other claims on this resource. @@ -33,22 +37,15 @@ interface Lockable { # lock. } -interface Claim extends (Persistent) { - update @0 ( update :Update ) -> ( error :Error ); - # Atomically update a resource via a claim. - # - # The parameter `update` is a list of `UpdateValue` that specify a list of behaviours to be - # updated with the associated data. The format of this data depends on and is defined by the - # behaviour. - # An update call is atomic, if any one of the UpdateValue can not be applied - # the entire update call fails and is not applied. A client may send multiple update calls in - # parallel to opt out of the atomic behaviour of update. The ordering in which multiple - # update calls are applied is not specified, a client MUST NOT rely on updates happening in the - # order they are sent. - # The returned `error` is NULL if the update call succeeded. - interface Error { +interface Claim extends (Notifiable) { + resource @0 () -> ( resource :Resource ); + # Pointer back to the resource this claim comes from. Primarily useful when restoring persisted + # claims or restoring after a connection failure. - } + traits @1 () -> Map(OID, AnyPointer); + + disown @2 (); + # Disown this claim } interface Lock extends (Claim) { diff --git a/notify.capnp b/notify.capnp index 346d9e2..46b78ed 100644 --- a/notify.capnp +++ b/notify.capnp @@ -3,19 +3,24 @@ using CSharp = import "programming_language/csharp.capnp"; $CSharp.namespace("FabAccessAPI.Schema"); -using import "state.capnp".State; -using import "state.capnp".Update; +using import "resource.capnp".Resource; +using import "utils.capnp".OID; +using import "utils.capnp".Map; -interface Notifyable { +interface Notifiable { + traits @0 () -> Map(OID, AnyPointer); +} + +interface Notify(State, Update) { state @0 () -> ( state :State ); # Returns the current state of a resource. - subscribe @1 ( subscriber :Subscriber ) -> ( subscription :Subscription ); + subscribe @1 ( subscriber :Subscriber(Update) ) -> ( subscription :Subscription ); # Subscribe to state updates. The passed in `subscriber` is an interface implemented on the # client side that a server calls to send update notifications. } -interface Subscriber { +interface Subscriber(Update) { update @0 ( update :Update ) -> (); # Called by a server when a new state was produced for this resource. This method MAY not be # called when a resource was updated but did not change its state. A server will only ever have diff --git a/resource.capnp b/resource.capnp index 6285712..d21116c 100644 --- a/resource.capnp +++ b/resource.capnp @@ -4,57 +4,82 @@ using CSharp = import "programming_language/csharp.capnp"; $CSharp.namespace("FabAccessAPI.Schema"); using import "persistent.capnp".Persistent; -using import "notify.capnp".Notifyable; +using import "notify.capnp".Notifiable; using import "interest.capnp".Interestable; using import "claim.capnp".Claimable; using import "claim.capnp".Lockable; using import "utils.capnp".OID; using import "utils.capnp".L10NString; +using import "utils.capnp".Map; -interface Resource extends (Persistent) { +struct Resource { # BFFH's smallest unit of a physical or abstract "thing". A resource can be as simple and # physical as a table, as complex as a PCB production line or as abstract as "people with # specific know-how are present". - describe @0 () -> Description; - # Return information about this resource. This information is usually rather static, but may - # change between calls. + description @0 :Describable; - caps @1 () -> ( notify :Notifyable, interest :Interestable, claim :Claimable, lock :Lockable ); - # return the capabilities an user has for this resource. - # `notify`: NULL if the user does not have permission to read this resource, or if this resource - # is not notifiable - # `interest`: NULL if this resource is not interestable or the user does not have permission to - # set interests for this resource. - # `claim`: NULL if the user does not have permission to write to this resource, or if this - # resource type does not support claiming. - # `lock`: NULL if the user does not have permission to manage this resource, or if this resource - # type does not support claiming or locking. + notify @1 :Notifiable; + # NULL if the user does not have permission to read this resource, or if this resource is not + # notifiable + + interest @2 :Interestable; + # NULL if this resource is not interestable or the user does not have permission to set + # interests for this resource. + + claim @3 :Claimable; + # NULL if the user does not have permission to write to this resource, or if this resource type + # does not support claiming. + + lock @4 :Lockable; + # NULL if the user does not have permission to manage this resource, or if this resource type + # does not support claiming or locking. +} + +interface Describable { + description @0 () -> Description; + # Return information about this resource. This information is usually static and does not + # change between calls. } struct Description { - types @0 :List(OID); - # The 'type' of Resource. Each OID in the list specifies certain behaviours that this Resource - # follows. + identifier @0 :Text; + # The unique identifier for this resource - urn @1 :Text; - # The URN of this resource. - - category @2 :Text; - # A category this resource belongs to. If a resource was not assigned a category this is NULL. - - name @3 :L10NString; + name @1 :L10NString; # A human-facing name for this resource. A name should be short and recognizable, and is meant # as the primary identifier for users to find a resource. - description @4 :L10NString; + description @2 :L10NString; # A human-facing description for this resource. Descriptions are longer-form text that give # additional information about a resource beyond a name. They are meant to provide either # further identifying information or important information that users should be actively shown # when selecting this resource. - wiki @5 :Text; - # An URI to further detailed information about this resource, e.g. in a wiki. This SHOULD be an - # http or https URL. + types @3 :List(OID); + # The 'type' of Resource. Each OID in the list specifies certain behaviours that this Resource + # follows. + + category @4 :Category; + # A category this resource belongs to. If a resource was not assigned a category this is empty, + # see the definition of [`Category`](struct::Category) for details. + + metadata @5 :Map(Text, Text); + # Metadata associated with this resource. This can be things like links to wikis or similar. + # Common keys are pre-defined as constants in this file. } + +struct Category { + # A category this resource belongs to. + + id @0 :Data; + # An unique ID for this category. If a resource was not assigned a category this is NULL. + + name @1 :L10NString; + # A human-facing name for this category. +} + +const metadataWiki :Text = "wiki"; +# An URI to further detailed information about this resource, e.g. in a wiki. This SHOULD be an +# https URL. diff --git a/resources.capnp b/resources.capnp index b71874e..99798e8 100644 --- a/resources.capnp +++ b/resources.capnp @@ -3,13 +3,12 @@ using CSharp = import "programming_language/csharp.capnp"; $CSharp.namespace("FabAccessAPI.Schema"); -using import "/capnp/rpc.capnp".SturdyRef; - using import "resource.capnp".Resource; +using import "claim.capnp".Claim; interface Resources { - restore @0 ( sturdy :SturdyRef ) -> ( resources :Resource ); - # Restore a previously saved SturdyRef pointing to a Resource + claimed @0 () -> ( claimed :List(Claim) ); + # Returns the list of valid claims the session owner of this `Resources` currently has. list @1 () -> ( resources :List(Resource) ); diff --git a/state.capnp b/state.capnp index b1a9a78..f9aa7d1 100644 --- a/state.capnp +++ b/state.capnp @@ -7,6 +7,8 @@ using import "utils.capnp".OID; interface State { get @0 ( oid :OID ) -> ( val :AnyPointer ); + # Return the value for the field specified by `oid`. + # If the field is not set or the resource does not support a field with that OID the returned `val` is NULL. } struct UpdateValue { diff --git a/utils.capnp b/utils.capnp index 217117b..befac02 100644 --- a/utils.capnp +++ b/utils.capnp @@ -61,3 +61,23 @@ using OID = Data; # a rather efficient encoding since almost all edges of the OID tree are smaller than 128 and thus # encode into one byte. X.208 does *not* limit the size of nodes! However, a reasonable size limit # is 128 bit per node, which is the size of the UUID nodes in the `2.25` subtree. + +struct Map(Key, Value) { + # Generic Key-Value-Map + + entries @0 :List(Entry); + struct Entry { + key @0 :Key; + value @1 :Value; + } +} + +struct Fallible(Ok, Error) { + union { + ok @0 :Ok; + err :group { + error @1 :Error; + description @2 :L10NString; + } + } +}