github.com/git-amp/amp-sdk-go@v0.7.5/amp/api.host.go (about)

     1  package amp
     2  
     3  import (
     4  	"net/url"
     5  
     6  	"github.com/git-amp/amp-sdk-go/stdlib/symbol"
     7  	"github.com/git-amp/amp-sdk-go/stdlib/task"
     8  )
     9  
    10  // Host allows app and transport services to be attached.
    11  // Child processes attach as it responds to client requests to "pin" cells via URLs.
    12  type Host interface {
    13  	task.Context
    14  
    15  	// Offers Go runtime and package level access to this Host's primary symbol and amp.App registry.
    16  	// The amp.Registry interface bakes security and efficiently and tries to serve as effective package manager.
    17  	Registry() Registry
    18  
    19  	// StartNewSession creates a new HostSession and binds its Msg transport to a stream.
    20  	StartNewSession(parent HostService, via Transport) (HostSession, error)
    21  }
    22  
    23  // Transport wraps a Msg transport abstraction, allowing a Host to connect over any data transport layer.
    24  // For example, a tcp-based transport as well as a dll-based transport are both implemented..
    25  type Transport interface {
    26  
    27  	// Describes this transport for logging and debugging.
    28  	Label() string
    29  
    30  	// Called when this stream should close because the associated parent host session is closing or has closed.
    31  	Close() error
    32  
    33  	// SendMsg sends a Msg to the remote client.
    34  	// ErrStreamClosed is used to denote normal stream close.
    35  	SendMsg(m *Msg) error
    36  
    37  	// RecvMsg blocks until it receives a Msg or the stream is done.
    38  	// ErrStreamClosed is used to denote normal stream close.
    39  	RecvMsg() (*Msg, error)
    40  }
    41  
    42  // HostService attaches to a amp.Host as a child, extending host functionality.
    43  type HostService interface {
    44  	task.Context
    45  
    46  	// StartService attaches a child task to a Host and starts this HostService.
    47  	// This service may retain the amp.Host instance so that it can make calls to StartNewSession().
    48  	StartService(on Host) error
    49  
    50  	// GracefulStop initiates a polite stop of this extension and blocks until it's in a "soft" closed state,
    51  	//    meaning that its service has effectively stopped but its Context is still open.
    52  	// Note this could any amount of time (e.g. until all open requests are closed)
    53  	// Typically, GracefulStop() is called (blocking) and then Context.Close().
    54  	// To stop immediately, Context.Close() is always available.
    55  	GracefulStop()
    56  }
    57  
    58  // HostSession in an open client session with a Host.
    59  // Closing is initiated via task.Context.Close().
    60  type HostSession interface {
    61  	task.Context    // Underlying task context
    62  	SessionRegistry // How symbols and types registered and resolved
    63  
    64  	// Called when this session is newly opened to set up the SessionRegistry
    65  	InitSessionRegistry(symTable symbol.Table)
    66  
    67  	// Returns the running AssetPublisher instance for this session.
    68  	AssetPublisher() AssetPublisher
    69  
    70  	// Returns info about this user and session
    71  	LoginInfo() Login
    72  
    73  	// Sends a readied Msg to the client for handling.
    74  	// If msg.ReqID == 0, the attr is sent to the client's session controller (for sending session meta messages).
    75  	// On exit, the given msg should not be referenced further.
    76  	SendMsg(msg *Msg) error
    77  
    78  	// PinCell resolves and pins a requested cell.
    79  	PinCell(req PinReq) (PinContext, error)
    80  
    81  	// Gets the currently running AppInstance for an AppID.
    82  	// If the requested app is not running and autoCreate is set, a new instance is created and started.
    83  	GetAppInstance(appID UID, autoCreate bool) (AppInstance, error)
    84  }
    85  
    86  // Registry is where apps and types are registered -- concurrency safe.
    87  type Registry interface {
    88  
    89  	// Registers an element value type (ElemVal) as a prototype under its AttrElemType (also a valid AttrSpec type expression).
    90  	// If an entry already exists (common for a type used by multiple apps), an error is returned and is a no-op.
    91  	// This and ResolveAttrSpec() allow NewElemVal() to work.
    92  	RegisterElemType(prototype ElemVal)
    93  
    94  	// When a HostSession creates a new SessionRegistry(), this populates it with its registered ElemTypes.
    95  	ExportTo(dst SessionRegistry) error
    96  
    97  	// Registers an app by its UUID, URI, and schemas it supports.
    98  	RegisterApp(app *App) error
    99  
   100  	// Looks-up an app by UUID -- READ ONLY ACCESS
   101  	GetAppByUID(appUID UID) (*App, error)
   102  
   103  	// Selects the app that best matches an invocation string.
   104  	GetAppForInvocation(invocation string) (*App, error)
   105  }
   106  
   107  // SessionRegistry manages a HostSession's symbol and type definitions -- concurrency safe.
   108  type SessionRegistry interface {
   109  
   110  	// Returns the symbol table for a session a technique sometimes also known as interning.
   111  	ClientSymbols() symbol.Table
   112  
   113  	// Translates a native symbol ID to a client symbol ID, returning false if not found.
   114  	NativeToClientID(nativeID uint32) (clientID uint32, found bool)
   115  
   116  	// Registers an ElemVal as a prototype under its element type name..
   117  	// This and ResolveAttrSpec() allow NewElemVal() to work.
   118  	RegisterElemType(prototype ElemVal) error
   119  
   120  	// Registers a block of symbol, attr, cell, and selector definitions for a client.
   121  	RegisterDefs(defs *RegisterDefs) error
   122  
   123  	// Resolves an AttrSpec into useful symbols, auto-registering the AttrSpec as needed.
   124  	// Typically used during AppInstance.OnNew() to get the AttrIDs that correspond to the AttrSpecs it will send later.
   125  	//
   126  	// If native === true, the spec is resolved with native symbols (vs client symbols).
   127  	//
   128  	// See AttrSpec docs.
   129  	ResolveAttrSpec(attrSpec string, native bool) (AttrSpec, error)
   130  
   131  	// Instantiates an attr element value for an AttrID -- typically followed by ElemVal.Unmarshal()
   132  	NewAttrElem(attrDefID uint32, native bool) (ElemVal, error)
   133  }
   134  
   135  // NewRegistry returns a new Registry
   136  func NewRegistry() Registry {
   137  	return newRegistry()
   138  }
   139  
   140  // PinContext wraps a client request to receive a cell's state / updates.
   141  type PinContext interface {
   142  	task.Context // Started as a CHILD of the amp.PinnedCell returned by AppInstance.PinCell()
   143  
   144  	PinReq // Originating request info
   145  
   146  	// Looks up the given AttrSpec and returns its AttrID.
   147  	// Returns 0 if the AttrSpec is not registered or not enabled within this PinContext.
   148  	GetAttrID(attrSpec string) uint32
   149  
   150  	// PushTx pushes the given tx to this PinContext
   151  	PushUpdate(tx *Msg) error
   152  
   153  	// App returns the resolved AppContext that is servicing this PinContext
   154  	App() AppContext
   155  }
   156  
   157  // PinReq is support wrapper for PinRequest, a client request to pin a cell.
   158  type PinReq interface {
   159  	Params() *PinReqParams
   160  	URLPath() []string
   161  }
   162  
   163  // PinReqParams implements PinReq
   164  type PinReqParams struct {
   165  	PinReq   PinRequest
   166  	PinCell  CellID
   167  	URL      *url.URL
   168  	ReqID    uint64    // Request ID needed to route to the originator
   169  	LogLabel string    // info string for logging and debugging
   170  	Outlet   chan *Msg // send to this channel to transmit to the request originator
   171  
   172  }