InfSession

InfSession — Basic session object and synchronization

Stability Level

Unstable, unless otherwise indicated

Synopsis

#include <libinfinity/common/inf-session.h>

enum                InfSessionStatus;
enum                InfSessionSyncStatus;
enum                InfSessionSyncError;
                    InfSession;
struct              InfSessionClass;
const GParameter *  inf_session_lookup_user_property    (const GParameter *params,
                                                         guint n_params,
                                                         const gchar *name);
GParameter *        inf_session_get_user_property       (GArray *array,
                                                         const gchar *name);
void                inf_session_user_to_xml             (InfSession *session,
                                                         InfUser *user,
                                                         xmlNodePtr xml);
void                inf_session_close                   (InfSession *session);
InfCommunicationManager * inf_session_get_communication_manager
                                                        (InfSession *session);
InfBuffer *         inf_session_get_buffer              (InfSession *session);
InfUserTable *      inf_session_get_user_table          (InfSession *session);
InfSessionStatus    inf_session_get_status              (InfSession *session);
InfUser *           inf_session_add_user                (InfSession *session,
                                                         const GParameter *params,
                                                         guint n_params,
                                                         GError **error);
void                inf_session_set_user_status         (InfSession *session,
                                                         InfUser *user,
                                                         InfUserStatus status);
void                inf_session_synchronize_from        (InfSession *session);
void                inf_session_synchronize_to          (InfSession *session,
                                                         InfCommunicationGroup *group,
                                                         InfXmlConnection *connection);
InfSessionSyncStatus  inf_session_get_synchronization_status
                                                        (InfSession *session,
                                                         InfXmlConnection *connection);
gdouble             inf_session_get_synchronization_progress
                                                        (InfSession *session,
                                                         InfXmlConnection *connection);
gboolean            inf_session_has_synchronizations    (InfSession *session);
InfCommunicationGroup * inf_session_get_subscription_group
                                                        (InfSession *session);
void                inf_session_set_subscription_group  (InfSession *session,
                                                         InfCommunicationGroup *group);
void                inf_session_send_to_subscriptions   (InfSession *session,
                                                         xmlNodePtr xml);

Object Hierarchy

  GEnum
   +----InfSessionStatus
  GObject
   +----InfSession
         +----InfAdoptedSession
         +----InfChatSession

Implemented Interfaces

InfSession implements InfCommunicationObject.

Properties

  "buffer"                   InfBuffer*            : Read / Write / Construct Only
  "communication-manager"    InfCommunicationManager*  : Read / Write / Construct Only
  "status"                   InfSessionStatus      : Read / Write / Construct Only
  "subscription-group"       InfCommunicationGroup*  : Read / Write
  "sync-connection"          InfXmlConnection*     : Read / Write / Construct Only
  "sync-group"               InfCommunicationGroup*  : Read / Write / Construct Only
  "user-table"               InfUserTable*         : Read / Write / Construct Only

Signals

  "close"                                          : Run Last
  "synchronization-begin"                          : Run Last
  "synchronization-complete"                       : Run Last
  "synchronization-failed"                         : Run Last
  "synchronization-progress"                       : Run Last

Description

InfSession represents an editing session. The actual type of document that is edited is not specified, so instantiating InfSession does not make any sense. You rather want to use a derived class such as InfTextSession. Normally, the InfcBrowser or InfdDirectory, respectively, already take care of instantiating the correct InfSession.

A session basically consists of the document being edited (also called buffer, see InfBuffer) and the users that are working on the document, see InfUserTable.

A session can either start in INF_SESSION_RUNNING state, in which it is created with the initial buffer and user table. It may also start in INF_SESSION_SYNCHRONIZING state. In this case, both buffer and user table are initially empty and are copied from another system over the network. When the copy is complete, the session enters INF_SESSION_RUNNING state.

To be notified about changes other users make to a session, you need to subscribe to the session (on client side), or wait for incoming subscriptions (on server side). This is normally done by infc_browser_iter_subscribe_session(). The first action that is performed upon subscription is a synchronization as described above. When the synchronization is complete, the "synchronization-complete" signal is emitted.

After subscription, one can observe modifications other users make, but it is not possible to make own modifications. Before doing so, a InfUser needs to be joined. This is done by client/server specific API such as infc_session_proxy_join_user() or infd_session_proxy_add_user(). The required parameters still depend on the actual note type, which is why most note implementations offer their own API to join a user.

Details

enum InfSessionStatus

typedef enum _InfSessionStatus {
  INF_SESSION_PRESYNC,
  INF_SESSION_SYNCHRONIZING,
  INF_SESSION_RUNNING,
  INF_SESSION_CLOSED
} InfSessionStatus;

InfSessionStatus defines in what state a session is in.

INF_SESSION_PRESYNC

The session is scheduled to be synchronized from a remote host. This can be useful if the session is needed to be present before the actual synchronization begins. Use inf_session_synchronize_from() to switch to INF_SESSION_SYNCHRONIZING.

INF_SESSION_SYNCHRONIZING

The session is currently being synchronized from a remote host. When done synchronizing, it will enter into INF_SESSION_RUNNING state.

INF_SESSION_RUNNING

The session is running and ready to synchronize other hosts. If a subscription group is set (see inf_session_set_subscription_group()), then changes to the underlying buffer are transmitted to all subscribed connections.

INF_SESSION_CLOSED

The session is closed and can no longer be used. The session enters this state if the synchronization fails in INF_SESSION_SYNCHRONIZING state or inf_session_close() is called.

enum InfSessionSyncStatus

typedef enum _InfSessionSyncStatus {
  INF_SESSION_SYNC_NONE,
  INF_SESSION_SYNC_IN_PROGRESS,
  INF_SESSION_SYNC_AWAITING_ACK
} InfSessionSyncStatus;

InfSessionSyncStatus represents the status of a synchronization. It is used by inf_session_get_synchronization_status().

INF_SESSION_SYNC_NONE

No synchronization is ongoing.

INF_SESSION_SYNC_IN_PROGRESS

Synchronization is currently in progress.

INF_SESSION_SYNC_AWAITING_ACK

All synchronization data has been sent (progress is 1.0), but we are still waiting for an acknowledgment from the remote site. Synchronization can no longer be cancelled, but it can stiff fail.

enum InfSessionSyncError

typedef enum _InfSessionSyncError {
  INF_SESSION_SYNC_ERROR_GOT_MESSAGE_IN_PRESYNC,
  INF_SESSION_SYNC_ERROR_UNEXPECTED_NODE,
  INF_SESSION_SYNC_ERROR_ID_NOT_PRESENT,
  INF_SESSION_SYNC_ERROR_ID_IN_USE,
  INF_SESSION_SYNC_ERROR_NAME_NOT_PRESENT,
  INF_SESSION_SYNC_ERROR_NAME_IN_USE,
  INF_SESSION_SYNC_ERROR_CONNECTION_CLOSED,
  INF_SESSION_SYNC_ERROR_SENDER_CANCELLED,
  INF_SESSION_SYNC_ERROR_RECEIVER_CANCELLED,
  INF_SESSION_SYNC_ERROR_UNEXPECTED_BEGIN_OF_SYNC,
  INF_SESSION_SYNC_ERROR_NUM_MESSAGES_MISSING,
  INF_SESSION_SYNC_ERROR_UNEXPECTED_END_OF_SYNC,
  INF_SESSION_SYNC_ERROR_EXPECTED_BEGIN_OF_SYNC,
  INF_SESSION_SYNC_ERROR_EXPECTED_END_OF_SYNC,

  INF_SESSION_SYNC_ERROR_FAILED
} InfSessionSyncError;

These are errors that can occur during a synchronization of a session. Additional errors may occur depending on the session type.

INF_SESSION_SYNC_ERROR_GOT_MESSAGE_IN_PRESYNC

Received a message in state INF_SESSION_PRESYNC. It is not processed because inf_session_synchronize_from() was not yet called.

INF_SESSION_SYNC_ERROR_UNEXPECTED_NODE

A message has been received that was not understood.

INF_SESSION_SYNC_ERROR_ID_NOT_PRESENT

An ID was not provided for a user in the session.

INF_SESSION_SYNC_ERROR_ID_IN_USE

The ID of a user is already in use by another user.

INF_SESSION_SYNC_ERROR_NAME_NOT_PRESENT

A name was not provided for a user in the session.

INF_SESSION_SYNC_ERROR_NAME_IN_USE

The name of a user is already in use by another user.

INF_SESSION_SYNC_ERROR_CONNECTION_CLOSED

The synchronization connection has been closed.

INF_SESSION_SYNC_ERROR_SENDER_CANCELLED

The sender has cancelled the synchronization.

INF_SESSION_SYNC_ERROR_RECEIVER_CANCELLED

The receiver has cancelled the synchronization.

INF_SESSION_SYNC_ERROR_UNEXPECTED_BEGIN_OF_SYNC

Received <sync-begin/> not a the beginning of the synchronization.

INF_SESSION_SYNC_ERROR_NUM_MESSAGES_MISSING

The <sync-begin/> message does not contain the number of synchronization messages to expect.

INF_SESSION_SYNC_ERROR_UNEXPECTED_END_OF_SYNC

The <sync-end/> message was not received at the end of the synchronization.

INF_SESSION_SYNC_ERROR_EXPECTED_BEGIN_OF_SYNC

The <sync-begin/> message was not received at the beginning of the synchronization.

INF_SESSION_SYNC_ERROR_EXPECTED_END_OF_SYNC

The <sync-end/> message was not received at the end of the synchronization.

INF_SESSION_SYNC_ERROR_FAILED

Generic error code when no further reason of failure is known.

InfSession

typedef struct _InfSession InfSession;

InfSession is an opaque data type. You should only access it via the public API functions.


struct InfSessionClass

struct InfSessionClass {
  /* Virtual table */
  void(*to_xml_sync)(InfSession* session,
                     xmlNodePtr parent);

  gboolean(*process_xml_sync)(InfSession* session,
                              InfXmlConnection* connection,
                              xmlNodePtr xml,
                              GError** error);

  InfCommunicationScope(*process_xml_run)(InfSession* session,
                                          InfXmlConnection* connection,
                                          xmlNodePtr xml,
                                          GError** error);

  GArray*(*get_xml_user_props)(InfSession* session,
                               InfXmlConnection* conn,
                               xmlNodePtr xml);

  void (*set_xml_user_props)(InfSession* session,
                             const GParameter* params,
                             guint n_params,
                             xmlNodePtr xml);

  gboolean(*validate_user_props)(InfSession* session,
                                 const GParameter* params,
                                 guint n_params,
                                 InfUser* exclude,
                                 GError** error);

  InfUser*(*user_new)(InfSession* session,
                      GParameter* params,
                      guint n_params);

  /* Signals */
  void(*close)(InfSession* session);

  void(*synchronization_begin)(InfSession* session,
                               InfCommunicationGroup* group,
                               InfXmlConnection* connection);

  void(*synchronization_progress)(InfSession* session,
                                  InfXmlConnection* connection,
                                  gdouble percentage);

  void(*synchronization_complete)(InfSession* session,
                                  InfXmlConnection* connection);

  void(*synchronization_failed)(InfSession* session,
                                InfXmlConnection* connection,
                                const GError* error);
};

This structure contains the virtual functions and default signal handlers of InfSession.

to_xml_sync ()

Virtual function that saves the session within a XML document. parent is the root node of the document. It should create as much nodes as possible within that root node and not in sub-nodes because these are sent to a client and it is not allowed that other traffic is put in between those nodes. This way, communication through the same connection does not hang just because a large session is synchronized.

process_xml_sync ()

Virtual function that is called for every node in the XML document created by to_xml_sync. It is supposed to reconstruct the session content from the XML data.

process_xml_run ()

Virtual function that is called for every received message while the session is running. Return INF_COMMUNICATION_SCOPE_GROUP if the message is designated for all group members (see also inf_communication_object_received() on this topic).

get_xml_user_props ()

Virtual function that creates a list of GParameters for use with g_object_newv() from a XML node.

set_xml_user_props ()

Virtual function that writes the passed user properties into a XML node.

validate_user_props ()

Virtual function that checks whether the given user properties are valid for a user join. This prevents a user join if there is already a user with the same name. If exclude is not NULL, then the function does ignore it when validating.

user_new ()

Virtual function that creates a new user object with the given properties.

close ()

Default signal handler for the "close" signal. This cancels currently running synchronization in InfSession.

synchronization_begin ()

Default signal handler for the "synchronization-begin" signal. The default handler queues the synchronization messages.

synchronization_progress ()

Default signal handler for the "synchronization-progress" signal.

synchronization_complete ()

Default signal handler for the "synchronization-complete" signal. If the session itself got synchronized (and did not synchronize another session), then the default handler changes status to INF_SESSION_RUNNING.

synchronization_failed ()

Default signal handler for the "synchronization-failed" signal. If the session itself got synchronized (and did not synchronize another session), then the default handler changes status to INF_SESSION_CLOSED.

inf_session_lookup_user_property ()

const GParameter *  inf_session_lookup_user_property    (const GParameter *params,
                                                         guint n_params,
                                                         const gchar *name);

Looks up the parameter with the given name in array.

params :

A pointer to an array of containing GParameter values.

n_params :

The number of elements in the aforementioned array

name :

Name to look up.

Returns :

A GParameter, or NULL.

inf_session_get_user_property ()

GParameter *        inf_session_get_user_property       (GArray *array,
                                                         const gchar *name);

Looks up the paremeter with the given name in array. If there is no such parameter, a new one will be created.

array :

A GArray containing GParameter values.

name :

Name to look up.

Returns :

A GParameter.

inf_session_user_to_xml ()

void                inf_session_user_to_xml             (InfSession *session,
                                                         InfUser *user,
                                                         xmlNodePtr xml);

This is a convenience function that queries user's properties and calls set_xml_user_props with them. This adds the properties of user to xml.

An equivalent user object may be built by calling the get_xml_user_props vfunc on xml and then calling the user_new vfunc with the resulting properties.

session :

A InfSession.

user :

A InfUser contained in session.

xml :

An XML node to which to add user information.

inf_session_close ()

void                inf_session_close                   (InfSession *session);

Closes a running session. When a session is closed, it unrefs all connections and no longer handles requests.

session :

A InfSession.

inf_session_get_communication_manager ()

InfCommunicationManager * inf_session_get_communication_manager
                                                        (InfSession *session);

Returns the communication manager for session.

session :

A InfSession.

Returns :

A InfCommunicationManager.

inf_session_get_buffer ()

InfBuffer *         inf_session_get_buffer              (InfSession *session);

Returns the buffer used by session.

session :

A InfSession.

Returns :

A InfBuffer.

inf_session_get_user_table ()

InfUserTable *      inf_session_get_user_table          (InfSession *session);

Returns the user table used by session.

session :

A InfSession.

Returns :

A InfUserTable.

inf_session_get_status ()

InfSessionStatus    inf_session_get_status              (InfSession *session);

Returns the session's status.

session :

A InfSession.

Returns :

The status of session.

inf_session_add_user ()

InfUser *           inf_session_add_user                (InfSession *session,
                                                         const GParameter *params,
                                                         guint n_params,
                                                         GError **error);

Adds a user to session. The user object is constructed via the user_new vfunc of InfSessionClass. This will create a new InfUser object by default, but may be overridden by subclasses to create different kinds of users.

Note that this function does not tell the other participants that the user was added. To avoid conflicts, normally only the publisher of the session can add users and notifies others accordingly. This is handled by InfdSessionProxy or InfcSessionProxy, respectively.

You should not call this function unless you know what you are doing.

session :

A InfSession.

params :

Construction parameters for the InfUser (or derived) object.

n_params :

Number of parameters.

error :

Location to store error information.

Returns :

The new InfUser, or NULL in case of an error.

inf_session_set_user_status ()

void                inf_session_set_user_status         (InfSession *session,
                                                         InfUser *user,
                                                         InfUserStatus status);

Changes the status of the given user which needs to have the INF_USER_LOCAL flag set for this function to be called. If the status is changed to INF_USER_UNAVAILABLE, then the user leaves the session. To rejoin use infc_session_proxy_join_user() or infd_session_proxy_add_user(), respectively for a proxy proxying session.

session :

A InfSession.

user :

A local InfUser from session's user table.

status :

New status for user.

inf_session_synchronize_from ()

void                inf_session_synchronize_from        (InfSession *session);

Switches session's status to INF_SESSION_SYNCHRONIZING. In INF_SESSION_PRESYNC, all messages from incoming the synchronizing connection are ignored, and no cancellation request is sent to the remote site if the status changes to INF_SESSION_CLOSED. The rationale behind that status is that one can prepare a session for synchronization but start the actual synchronization later, after having made sure that the remote site is ready to perform the synchronization.

session :

A InfSession in status INF_SESSION_PRESYNC.

inf_session_synchronize_to ()

void                inf_session_synchronize_to          (InfSession *session,
                                                         InfCommunicationGroup *group,
                                                         InfXmlConnection *connection);

Initiates a synchronization to connection. On the other end of connection, a new session with the sync-connection and sync-group construction properties set should have been created. group is used as a group in the connection manager. It is allowed for group to have another InfCommunicationObject than session, however, you should forward the InfCommunicationObject messages your object receives to session then. Also, connection must already be present in group, and should not be removed until synchronization finished.

A synchronization can only be initiated if session is in state INF_SESSION_RUNNING.

session :

A InfSession in status INF_SESSION_RUNNING.

group :

A InfCommunicationGroup.

connection :

A InfConnection.

inf_session_get_synchronization_status ()

InfSessionSyncStatus  inf_session_get_synchronization_status
                                                        (InfSession *session,
                                                         InfXmlConnection *connection);

If session is in status INF_SESSION_SYNCHRONIZING, this always returns INF_SESSION_SYNC_IN_PROGRESS if connection is the connection with which the session is synchronized, and INF_SESSION_SYNC_NONE otherwise.

If session is in status INF_SESSION_RUNNING, this returns the status of the synchronization to connection. INF_SESSION_SYNC_NONE is returned, when there is currently no synchronization ongoing to connection, INF_SESSION_SYNC_IN_PROGRESS is returned, if there is one, and INF_SESSION_SYNC_AWAITING_ACK if the synchronization is finished but we are waiting for the acknowledgement from the remote site that all synchronization data has been progressed successfully. The synchronization can still fail in this state but it can no longer by cancelled.

If session is in status $INF_SESSION_CLOSED, this always returns INF_SESSION_SYNC_NONE.

session :

A InfSession.

connection :

A InfXmlConnection.

Returns :

The synchronization status of connection.

inf_session_get_synchronization_progress ()

gdouble             inf_session_get_synchronization_progress
                                                        (InfSession *session,
                                                         InfXmlConnection *connection);

This function requires that the synchronization status of connection is INF_SESSION_SYNC_IN_PROGRESS or INF_SESSION_SYNC_AWAITING_ACK (see inf_session_get_synchronization_status()). Then, it returns a value between 0.0 and 1.0 specifying how much synchronization data has already been transferred to the remote site.

Note that if the session is in status INF_SESSION_RUNNING, it is possible that this function returns 1.0 (i.e. all data has been transmitted) but the synchronization is not yet complete, because the remote site must still acknowledge the synchronization. The synchronization then is in status INF_SESSION_SYNC_AWAITING_ACK.

session :

A InfSession.

connection :

A InfXmlConnection.

Returns :

A value between 0.0 and 1.0.

inf_session_has_synchronizations ()

gboolean            inf_session_has_synchronizations    (InfSession *session);

Returns whether there are currently ongoing synchronizations. If the session is in status INF_SESSION_SYNCHRONIZING, then this returns always TRUE, if it is in INF_SESSION_CLOSED, then it returns always FALSE. If the session is in status INF_SESSION_RUNNING, then it returns TRUE when the session is currently at least synchronized to one connection and FALSE otherwise.

session :

A InfSession.

Returns :

Whether there are ongoing synchronizations.

inf_session_get_subscription_group ()

InfCommunicationGroup * inf_session_get_subscription_group
                                                        (InfSession *session);

Returns the subscription group for session, if any.

session :

A InfSession.

Returns :

A InfCommunicationGroup, or NULL.

inf_session_set_subscription_group ()

void                inf_session_set_subscription_group  (InfSession *session,
                                                         InfCommunicationGroup *group);

Sets the subscription group for session. The subscription group is the group in which all connections subscribed to the session are a member of.

InfSession itself does not deal with subscriptions, so it is your job to keep group up-to-date (for example if you add non-local users to session). This is normally done by a so-called session proxy such as InfcSessionProxy or InfdSessionProxy, respectively.

session :

A InfSession.

group :

A InfCommunicationGroup.

inf_session_send_to_subscriptions ()

void                inf_session_send_to_subscriptions   (InfSession *session,
                                                         xmlNodePtr xml);

Sends a XML message to the all members of session's subscription group. This function can only be called if the subscription group is non-NULL. It takes ownership of xml.

session :

A InfSession.

xml :

The message to send.

Property Details

The "buffer" property

  "buffer"                   InfBuffer*            : Read / Write / Construct Only

The buffer in which the document content is stored.


The "communication-manager" property

  "communication-manager"    InfCommunicationManager*  : Read / Write / Construct Only

The communication manager used for sending requests.


The "status" property

  "status"                   InfSessionStatus      : Read / Write / Construct Only

Current status of the session.

Default value: INF_SESSION_RUNNING


The "subscription-group" property

  "subscription-group"       InfCommunicationGroup*  : Read / Write

Communication group of subscribed connections.


The "sync-connection" property

  "sync-connection"          InfXmlConnection*     : Read / Write / Construct Only

Connection which synchronizes the initial session state.


The "sync-group" property

  "sync-group"               InfCommunicationGroup*  : Read / Write / Construct Only

Communication group in which to perform synchronization.


The "user-table" property

  "user-table"               InfUserTable*         : Read / Write / Construct Only

User table containing the users of the session.

Signal Details

The "close" signal

void                user_function                      (InfSession *session,
                                                        gpointer    user_data)      : Run Last

This signal is emitted if the session is closed. Note that this signal is not called as a client if the connection to the sessions has merely been lost, only the relevant InfXmlConnection has its "status" property changed.

session :

The InfSession that is being closed

user_data :

user data set when the signal handler was connected.

The "synchronization-begin" signal

void                user_function                      (InfSession            *session,
                                                        InfCommunicationGroup *group,
                                                        InfXmlConnection      *connection,
                                                        gpointer               user_data)       : Run Last

This signal is emitted whenever the session is started to be synchronized to another connection. Note that, in contrast to "synchronization-progress", "synchronization-failed" and "synchronization-complete" it cannot happen that the signal is emitted when session is being synchronized itself, because that can happen at construction time only when no one had a chance to connect signal handlers anyway.

session :

The InfSession that is synchronizing.

group :

The InfCommunicationGroup used for synchronization.

connection :

The InfXmlConnection to which the session is synchronized.

user_data :

user data set when the signal handler was connected.

The "synchronization-complete" signal

void                user_function                      (InfSession       *session,
                                                        InfXmlConnection *connection,
                                                        gpointer          user_data)       : Run Last

This signal is emitted when synchronization has completed, in addition to "synchronization-progress" with a progress value of 1.0.

If a callback is connected before the default handler, it can find out whether the remote side is synchronizing the local side by comparing sessions's status with INF_SESSION_SYNCHRONIZING. The default signal handler sets the status to INF_SESSION_RUNNING, so checking afterwards is not too useful.

session :

The InfSession that has or was synchronized

connection :

The InfXmlConnection through which synchronization happened

user_data :

user data set when the signal handler was connected.

The "synchronization-failed" signal

void                user_function                      (InfSession       *session,
                                                        InfXmlConnection *connection,
                                                        gpointer          error,
                                                        gpointer          user_data)       : Run Last

This signal is emitted when synchronization has failed before its completion due to malformed data from the other side or network failure.

If this happens during initial synchronization, "close" is emitted as well at this point.

session :

The InfSession that failed to synchronize or be synchronized

connection :

The InfXmlConnection through which synchronization happened

error :

A pointer to a GError object with details on the error

user_data :

user data set when the signal handler was connected.

The "synchronization-progress" signal

void                user_function                      (InfSession       *session,
                                                        InfXmlConnection *connection,
                                                        gdouble           progress,
                                                        gpointer          user_data)       : Run Last

This signal is emitted whenever a new XML node has been sent or received over connection as part of a synchronization. The process is completed when progress reaches the value 1.0. At this point, "synchronization-complete" is also emitted.

If session's status is INF_SESSION_SYNCHRONIZING, the local side is being synchronized by the remote side. If the status is INF_SESSION_RUNNING, the local side is updating the remote side.

session :

The InfSession that is synchronizing or being synchronized

connection :

The InfXmlConnection through which progress is made

progress :

A gdouble value ranging from 0.0 to 1.0.

user_data :

user data set when the signal handler was connected.