kernel.api

API of the kernel.

This API is exposed to consumers (i.e., client and server sites). Most details of the kernel’s data structures are encapsulated and hidden from the consumer.

Notation used in this documentation:

  • TODO marks missing features
  • OPTIMIZE marks possible optimizations
  • & at the end of a variable denotes that it is passed as an atom
  • _ at the beginning of a function name avoids name clashes with Clojure built-ins
  • ! at the end of a function name signifies that it reads or mutates the global context

Below, we describe the client, server and operations API. Some general remarks:

  • Note that unless otherwise specified, all calls to the API must be atomic (not interrupted) and from a single thread, as no synchronization is done.
  • Further, every action specified must be done as soon as possible (e.g., right after a user left, the leave message has to be propagated), before any other API functions are called. In particular, while changes are still being reflected in the user interface, no API calls are allowed.
  • Unless otherwise specified, periodically and for a while can refer to arbitrary periods of time, although it would be reasonable to use the same time periods at all sites.
  • The system is considered frozen whenever clientReceiveMessage reports conflicts. The system is only un-frozen when all conflicts are resolved.
  • When a client wants to leave, no special API call is necessary. It can simply discard all its metadata and notify the server that it is leaving. TODO: Right now, no timeout for leaving is considered. In other words, a site can not join again using the same site identifier and context once left, and it must register as a new site (no short-time offline editing).
  • The server does not generate messages itself (apart from occasional explicit heartbeats).
  • For more information on the individual operations, refer to kernel.core.compound-operation.

Data structures that are intended to be sent over the wire to other sites are serialized with Transit.

clientGC

(clientGC)

Periodically (and when no other API calls are in progress and the system is not frozen), the client must call clientGC.

clientGenerateHeartbeat

(clientGenerateHeartbeat)

If no operations have been generated for a while (and when no other API calls are in progress and the system is not frozen), the client must call clientGenerateHeartbeat and send the resulting message to the server. This is to ensure smooth garbage collection.

clientGenerateInverseOperation

(clientGenerateInverseOperation)

TODO: Generate inverse operations.

clientGenerateOperation

(clientGenerateOperation PO-sequence)

At any time the system is not frozen, the client may call clientGenerateOperation with a valid PO sequence (see operations API) to generate and immediately apply a new operation. TODO: Right now, the PO sequence is not sanity-checked, so the client is responsible to respect basic consistency rules (e.g., only submit operations that make sense on the current feature model). clientGenerateOperation returns a feature model that the client may consume. It also returns an operation message that the client must send to the server.

clientInitialize

(clientInitialize site-ID context)

When a client first enters the system, it announces itself at the server. The server assigns it a site identifier and an initial context, which the client must call clientInitialize with.

clientReceiveMessage

(clientReceiveMessage message)

When a message arrives from the server, the client must call clientReceiveMessage with the received message. The call returns either a new feature model that may be consumed by the client, or a conflict descriptor, which carries information about how emerged conflicts may be resolved.

clientResolveConflict

(clientResolveConflict MCG-ID)

When all sites have agreed on one version after a conflict has been detected (which is coordinated externally by the server), every client must call clientResolveConflict with the agreed version. The call returns the feature model that has been resolved to.

getContext

(getContext)

Returns the global context.

logProfile

(logProfile)

operationCompose

(operationCompose & PO-sequences)

Composes multiple compound operations into one compound operation.

operationCreateConstraint

(operationCreateConstraint formula)

Creates a constraint and initializes it with a given propositional formula.

operationCreateFeatureAbove

(operationCreateFeatureAbove & IDs)

Creates a feature above a set of sibling features.

operationCreateFeatureBelow

(operationCreateFeatureBelow parent-ID)

Creates a feature below another feature.

operationMoveFeatureSubtree

(operationMoveFeatureSubtree ID parent-ID)

Moves an entire feature subtree rooted at a feature below another feature.

operationRemoveConstraint

(operationRemoveConstraint ID)

Removes a constraint.

operationRemoveFeature

(operationRemoveFeature ID)

Removes a single feature.

operationRemoveFeatureSubtree

(operationRemoveFeatureSubtree ID)

Removes an entire feature subtree rooted at a feature.

operationSetConstraint

(operationSetConstraint ID formula)

Sets the propositional formula of a constraint.

operationSetFeatureGroupType

(operationSetFeatureGroupType ID group-type-str)

Sets the group type attribute of a feature.

operationSetFeatureOptional

(operationSetFeatureOptional ID optional?)

Sets the optional attribute of a feature.

operationSetFeatureProperty

(operationSetFeatureProperty ID property-str value)

Sets some additional property of a feature.

serverForwardMessage

(serverForwardMessage message)

After receiving a message from a client, the server must call serverForwardMessage with the received message. The returned message is then forwarded to all sites but the original site.

serverGC

(serverGC)

Periodically (and when no other API calls are in progress and the system is not frozen), the server must call serverGC.

serverGenerateHeartbeat

(serverGenerateHeartbeat)

If the server has not forwarded any operations for a while (and when no other API calls are in progress and the system is not frozen), the server must call serverGenerateHeartbeat and send the resulting message to all client sites. This may happen for example when only one client site is connected.

serverInitialize

(serverInitialize initial-FM)

When a client first enters the system and requests to edit a given feature model, the server must call serverInitialize with said feature model.

serverResolveConflict

(serverResolveConflict MCG-ID)

When all sites have agreed on one version after a conflict has been detected (which is coordinated externally by the server), the server must call serverResolveConflict with the agreed version.

serverSiteJoined

(serverSiteJoined site-ID)

Whenever a new site requests to join, the server must call serverSiteJoined and send the returned initial context to the site. It also has to forward the returned heartbeat message to all other sites immediately. The new site’s identifier may be chosen by the client or server site, as long as it is unique. OPTIMIZE: The conflict cache and feature model may be omitted from the initial context to save network bandwidth, as they can be produced from the other data structures. However, this imposes additional time complexity for the newly joined site, so for now we just transmit everything.

The heartbeat message is generated because directly after the join, the server has to notify all other sites about the new site. This may be done by blocking the server until the new site sends its first heartbeat, but it is more efficient to generate this heartbeat message directly at the server (which is equivalent) and forward it everyone else immediately.

serverSiteLeft

(serverSiteLeft site-ID)

When a site leaves, the server must call serverSiteLeft and forward the returned leave message to all other sites immediately.

setContext

(setContext context)

Sets the global context. May be used to switch between different contexts, e.g., when editing different feature models.

setGenerateIDFunction

(setGenerateIDFunction generate-ID-fn)

Sets a function that is used to generate unique identifiers. This function is only used on the client. generate-ID-fn is expected to take no arguments and return a UUIDv4 string.

setLoggerFunction

(setLoggerFunction logger-fn)

Sets a function that is used to allow for verbose logging. logger-fn is expected to take one string argument and not return anything.

setSemanticRulesFunction

(setSemanticRulesFunction semantic-rules-fn)

Sets a sequence of functions that are used to check semantic consistency of a feature model. Each function is expected to take an encoded feature model and return true if the feature model is inconsistent, false otherwise.

stats-accumulator