spree man page on Inferno

Man page or keyword search:  
man Server   579 pages
apropos Keyword Search (all sections)
Output format
Inferno logo
[printable version]

SPREE(2)							      SPREE(2)

NAME
       Spree - distributed interactive sessions.

SYNOPSIS
       include "sys.m";
       include "draw.m";
       include "sets.m";
       include "spree.m";
       spree := load Spree Spree->PATH;
       Range, Object, Clique, Member: import spree;
       Set: import Sets;
       Archive: import Archives;

       Range: adt {
	   start:  int;
	   end:	   int;
       };

       Object: adt {
	   transfer:	       fn(o: self ref Object,
		   r: Range, dst: ref Object, i: int);
	   setvisibility:      fn(o: self ref Object,
		   visibility: Set);
	   setattrvisibility:  fn(o: self ref Object,
		   name: string, visibility: Set);
	   setattr:	   fn(o: self ref Object,
		   name: string, val: string, vis: Set);
	   getattr:	   fn(o: self ref Object, name: string): string;
	   delete:     fn(o: self ref Object);
	   deletechildren: fn(o: self ref Object, r: Range);

	   id:	   int;
	   parentid:   int;
	   children:   array of ref Object;
	   objtype:    string;
	   visibility: Set;
	   # ...private data
       };

       Clique: adt {
	   new:	      fn(parent: self ref Clique, archive: ref Archive,
			   owner: string): (int, string, string);
	   newobject: fn(clique: self ref Clique, parent: ref Object,
		   visibility: int, objtype: string): ref Object;
	   action:   fn(clique: self ref Clique, cmd: string,
		      objs: list of int, rest: string, whoto: int);
	   member:   fn(clique: self ref Clique, id: int): ref Member;
	   start:    fn(clique: self ref Clique);
	   breakmsg: fn(clique: self ref Clique, whoto: Sets->Set);
	   members:  fn(clique: self ref Clique): list of ref Member;
	   owner:    fn(clique: self ref Clique): string;
	   hangup:   fn(clique: self ref Clique);
	   notify:   fn(clique: self ref Clique, cliqueid: int, msg: string);

	   objects:  array of ref Object;
	   cliqueid: int;
	   # ...private data
       };

       Member: adt {
	   obj:	   fn(m: self ref Member, id: int): ref Object;
	   del:	   fn(m: self ref Member, suspend: int);

	   id:	   int;
	   name:   string;
	   # ...private data
       };

       Engine: module {
	    init:		fn(srvmod: Spree, clique: ref Clique, argv: list of string): string;
	    command:  fn(member: ref Member, e: string): string;
	    join:		fn(member: ref Member , e: string, suspended: int): string;
	    leave:	   fn(member: ref Member): int;
	    notify:	   fn(fromid: int, s: string);
	    readfile:	   fn(f: int, offset: big, count: int): array of byte;
       };

       Archives: module {
	    Archive: adt {
		 argv:		list of string;		      # how to restart the session.
		 members:  array of string;		 # members involved.
		 info:		list of (string, string);     # any other information.
		 objects:  array of ref Object;
	    };
	    init:		fn(mod: Spree);
	    write:	   fn(clique: ref Clique, info: list of (string, string), file: string, members: Set): string;
	    read:		fn(file: string): (ref Archive, string);
	    readheader:	   fn(file: string): (ref Archive, string);
       };

       rand:   fn(n: int): int;

DESCRIPTION
       Spree  provides a general server interface that allows sets of distrib‐
       uted clients, cliques, to interact in a	controlled  manner,  with  the
       interaction  mediated  by Limbo modules, known as engines.  Each engine
       decides on the rules of its particular clique; the engine interface  is
       described at the end of this manual page, under ``Module Interface''.

       This manual page describes the interface as presented to an engine once
       it has been loaded by spree.  A loaded instance of an engine is respon‐
       sible  for  a  particular clique, in which one or more members partici‐
       pate. Messages sent by members are interpreted  by  the	engine,	 which
       responds	 by making changes to the hierarchical object database held by
       the clique.  Behind the scenes spree distributes updates to this	 data‐
       base  to	 members  of  the  clique  as  appropriate  (see  spree(4) for
       details).

   Objects and visibility
       Objects hold a clique's visible state. An object has a  unique  integer
       id,  which  is  an index into the array clique.objects; it also holds a
       set of attribute-value pairs, a type, and zero or more  child  objects.
       Together,  all  the  objects  in	 the  clique form a hierarchical tree,
       rooted at the root object (id 0), which always exists.  Each  attribute
       and  each object also has an associated visibility set, the set of mem‐
       ber that sees updates to the attributes or the children of the  object.
       Each  member has a unique id; in a visibility set (see sets(2)), a mem‐
       ber is ``visible'' if the set contains the member's id.

       Note that the visibility set of an object does not alter the visibility
       of  that	 object's  attributes,	but  only that of its children (and of
       their children: in general an object is visible	to  a  member  if  the
       intersection  of	 all its ancestors' visibility sets contains that mem‐
       ber).

       Objects can be transferred inside the  hierarchy	 from  one  parent  to
       another. If an object is moved to a parent whose visibility conceals it
       from a member, then it will appear to that member to have been deleted;
       if it is later made visible, then it will be recreated for that member.
       A clique engine can almost always ignore this technicality, except  for
       one  thing:  the	 identifier used by a particular member to identify an
       object is not necessarily the same as that used by the  clique  engine.
       Thus  when  an  engine  receives an object id in a member's message, it
       should convert it using the member.obj() function.

   Clique
       The Clique type holds all the objects in a clique. It allows  the  cre‐
       ation  of new objects, and provides a way of communicating with members
       directly.  All data members of a Clique should be treated as read-only.

       clique.objects
		 This array holds the objects in the clique.  An  object  with
		 identifier id is found at clique.objects[id].

       clique.new(archive,owner)
		 New  creates a new clique.  Archive is an archive of the game
		 to be created; archive.argv should be non-nil; its first ele‐
		 ment  should name the engine to be loaded (as a path relative
		 to the engine module directory, and without the  .dis	exten‐
		 sion).

       clique.newobject(parent, visibility, objtype)
		 Newobject  creates  a new object at the end of parent's chil‐
		 dren; If parent is nil, the new object is created  under  the
		 root  object.	 The new object has visibility visibility, and
		 type objtype.	An object's type cannot be changed once it has
		 been created.

       clique.action(cmd, objs, rest, whoto)
		 Action	 sends a message to some members without affecting the
		 object hierarchy. It can be used  to  send  transient	events
		 that  have  no	 meaning  when stored statically (for example,
		 network latency probes).  The message is sent to the  set  of
		 members  given	 by  whoto.   Objs  is assumed to be a list of
		 object ids, which are converted appropriately for each member
		 receiving the message; the final message is a string built by
		 concatenating cmd, the list of object ids,  and  rest,	 sepa‐
		 rated by spaces.

       clique.breakmsg(whoto)
		 Messages  are	usually	 sent  to  clients in an uninterrupted
		 stream (as  documented	 in  spree(4)),	 with  a  single  read
		 returning  a  potentially  large  set	of messages.  Breakmsg
		 arranges that subsequent messages  received  by  the  members
		 specified  in whoto will see not be merged with messages sent
		 prior to the call to breakmsg.	 This is used to enable a  new
		 client	 module	 to be started without needing to pass it data
		 received in the previous read.

       clique.member(id)
		 Member yields the member corresponding to identifier  id,  or
		 nil if there is none.

       clique.membernamed(name)
		 Membernamed  searches	for  a member of clique named name and
		 returns it if it finds it, otherwise nil.

       clique.members()
		 Members returns a list of all the members of clique,  includ‐
		 ing those that have been suspended.

       clique.owner()
		 Owner	returns	 the name of the owner of the clique; i.e. the
		 user that created it.

       clique.hangup()
		 Hangup terminates a game and informs all the players of  that
		 fact.

       clique.notify(cliqueid,msg)
		 Notify sends an informational message to another clique.  The
		 clique so referenced must be either the parent or a child  of
		 clique.   The	message	 is  not  sent synchronously, and care
		 should be taken not to send messages that can cause an indef‐
		 inite recursion.

   Member
       The Member type represents a member of a clique.

       member.id The member's identifier is an integer	unique across all cur‐
		 rent members of the clique, but ids of members that have left
		 the  clique  will be reused.  There may not be two members of
		 the same name in the same clique.

       member.name
		 Name holds the authenticated name of  the  member.   This  is
		 necessarily unique over the members of a clique.

       member.obj(id)
		 Obj  converts	from  a member's external object identifier to
		 the clique's local Object that it represents. It returns  nil
		 if there is no such object.

       member.del(suspend)
		 Del  deletes  member  from  the clique; no more requests from
		 member will be received by the clique engine.	If suspend  is
		 non-zero, if a member of the same name joins again it will be
		 allocated the same object id, allowing a member to leave  and
		 join again without losing state.

   Object
       The  Object type is the basic unit of clique engine state.  An object's
       children can be selectively concealed from members; it holds a  set  of
       (attribute, value)  pairs,  each	 of  which  can be concealed likewise.
       Where an argument r, of Range type is used, it refers to a range of  an
       object's	 children starting at index r.start, and finishing at r.end-1.
       All the data members of an Object should be treated as read-only.

       obj.setattr(name, val, vis)
		 Setattr sets attribute name in obj to val.  If the  attribute
		 is  being  created  for the first time, then it will be given
		 visibility vis.  Name should be  non-empty,  and  should  not
		 contain  any  space characters.  Note that it is not possible
		 for an attribute to refer directly to an object by its	 iden‐
		 tifier;  if  this  facility  is  needed,  another identifying
		 scheme should be used. This also applies  to  member  identi‐
		 fiers,	 which	will  change if the clique is saved and loaded
		 again.

       obj.getattr(name)
		 Getattr yields the current value of  the  attribute  name  in
		 obj.  If an attribute is not set, it yields nil.

       obj.delete()
		 Delete removes obj from the object hierarchy.

       obj.deletechildren(r)
		 Deletechildren deletes children in range r from obj.

       obj.transfer(r, dst, i)
		 Transfer  transfers  the children in range r from obj to just
		 before the object at index i in dst.  It is  permissible  for
		 obj and dst to be the same object.

       obj.setvisibility(visibility)
		 Setvisibility	allows	the set of members given in visibility
		 to see the children of obj, and denies access to all  others.
		 Members are notified of the change.

       obj.setattrvisibility(name, visibility)
		 Setattrvisibility allows the set of members given in visibil‐
		 ity to see the value of  obj's	 attribute  name,  and	denies
		 access	 to  all  others.   Members  are  not  notified of the
		 change; if there is a need to	communicate  the  fact	of  an
		 attribute becoming invisible to members, it should be done by
		 using another (visible) attribute to communicate the change.

   Archives
       The Archives module provides a means of committing a clique  to	perma‐
       nent  storage  and retrieving it later.	It should first be initialised
       by calling init, passing the Spree module in mod.  Write writes	clique
       to the file file.  Info gives a set of attributes and values associated
       with the clique; members gives the set of clique members for which vis‐
       ibility	information will be archived; visibility information for other
       members is forgotten.

       Read opens file and returns it as an Archive adt, say a.	 A.argv	 holds
       the  command line arguments to the clique module (including the name of
       the module, its first  element);	 a.members  gives  the	names  of  all
       archived	 members  - the id of an archived member is given by its index
       in the array; a.info gives the list of attributes an values  as	stored
       by  write; a.objects holds the clique objects.  Readheader is just like
       read except that it parses the header only, so will return  an  Archive
       adt such that a.objects is nil.

   Module Interface
       An  engine module, mod, must implement the following functions. Where a
       function returns a string, it is interpreted as an  error  response  to
       the  member  responsible	 for the request; an empty string signifies no
       error.

       mod->init(srvmod,clique,argv)
	      Init initialises the clique engine.  Clique is the  clique  that
	      the  engine is controlling, and srvmod is the Spree module hold‐
	      ing its associated data.	An error response from	this  function
	      causes the clique to be aborted.	Argv gives a list of arguments
	      to the engine, starting with its module name.

       mod->join(member,e,suspended)
	      Member has made a request to join the clique; an error  response
	      causes the request to be refused, otherwise the member joins the
	      clique.  E is a message from the client about how it would  like
	      to  join the clique (e.g.	 join, watch, etc).  Suspended is non-
	      zero if the member was previously suspended from the clique.

       mod->leave(member)
	      Member has left the clique.  If leave returns zero,  the	member
	      will  not be deleted from the clique, but merely suspended until
	      they should join again.

       mod->command(member, e)
	      Member has sent the command e.  The command usually follows  the
	      simple  message conventions used in spree(4), i.e. simple space-
	      separated tokens.

       mod->notify(cliqueid,s)
	      A notification, s, has been posted to the current clique by  the
	      clique  identified  by cliqueid.	The posting clique is either a
	      parent or a child of the current clique.

       mod.

EXAMPLE
       The following is a small, but working example of a clique  engine  that
       acts  as a chat server (parsing error checking omitted, and white-space
       compressed to save paper):

       implement Cliquemodule;
       include "sys.m";
	   sys: Sys;
       include "draw.m";
       include "../spree.m";
	   spree: Spree;
	   Clique, Member: import spree;
       clique: ref Clique;
       clienttype(): string
       {
	   return "chat";
       }
       init(g: ref Clique, srvmod: Spree): string
       {
	   (sys, clique, spree) = (load Sys Sys->PATH, g, srvmod);
	   return nil;
       }
       join(nil: ref Member): string
       {
	   return nil;
       }
       leave(nil: ref Member)
       {
       }
       command(member: ref Member, cmd: string): string
       {
	   clique.action("say " + string member.id + " " + cmd, nil, nil, ~0);
	   return nil;
       }

SOURCE
       /appl/cmd/cliques/spree.b

SEE ALSO
       spree(4), spree-objstore(2), spree-cardlib(2), spree-allow(2),

BUGS
       The reuse of object ids can lead to problems when objects  are  deleted
       and recreated on the server before clients become aware of the changes.

								      SPREE(2)
[top]

List of man pages available for Inferno

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net