4.3 Receiving Cluster Object Event Indications

The following example shows how a protocol client receives event indications for when any group is added or deleted to the cluster configuration and when changes in state for a resource named "Resource1" occur.

This example assumes that the client has provided a higher-level programming abstraction in which its callers can create notification ports, register event filters, and receive cluster event indications. Underneath this abstraction, the client maintains the necessary data structures and queuing mechanism in order to accomplish this functionality.

One possible organization is for the client to maintain a data structure for every notification port it creates and from that, a linked set of data structures for event filter/context value registered by the caller for that port. Due to the blocking nature of the ApiGetNotify method (section 3.1.4.1.66 for protocol version 2 or section 3.1.4.2.66 for protocol version 3), the client also maintains a separate thread of execution that can retrieve event indications from the server and post them to the client-side queue. This allows the client's callers to register additional event filters after the port has been activated by the registration of its first event filter. The following diagram shows the client-side data organization of this abstraction.

Message flow: Registering and receiving events from a notification portFigure 8: Client/server data organization for a notification port abstraction

The following diagram depicts the message flow for this example.

Message flow: Registering and receiving events from a notification port

Figure 9: Message flow: Registering and receiving events from a notification port

First, the client initializes an RPC connection to the cluster, as specified in section 3.2.3. Any implementation-specific method can be used to locate the cluster. The client reserves the HCLUSTER_RPC context handle, obtained in the Reconnect Logic Initialization (section 3.2.3.3), for invocation of ApiAddNotifyCluster described in the following paragraphs.

The client next obtains an HRES_RPC context handle to the resource by calling ApiOpenResource (section 3.1.4.1.9 for protocol version 2 or section 3.1.4.2.9 for protocol version 3) with the lpszResourceName parameter set to the null-terminated Unicode string "Resource1".

The caller notifies the client through the programming abstraction to create a new notification port. The client obtains an HNOTIFY_RPC context handle on behalf of the caller by calling the ApiCreateNotify (section 3.1.4.1.56 for protocol version 2, or 3.1.4.2.56 for protocol version 3) method. A new client-side notification data structure is allocated and initialized with the context handle of the port and the pointer to the list of filters set to NULL. A separate thread of execution is started and calls the ApiGetNotify method; this is called the port service thread. This method will not complete because no event filters have been registered.

The caller now registers an event filter with the client that causes the server to provide an indication each time a group is created or deleted. The client creates an event filter data structure, initializes it with the caller supplied data, and links it to the notification port data structure. The client calls ApiAddNotifyCluster (section 3.1.4.1.58 for protocol version 2 or section 3.1.4.2.58 for protocol version 3) with the following:

  • The hNotify parameter set to the HNOTIFY_RPC context handle obtained in the previous step.

  • The hCluster parameter set to the HCLUSTER_RPC context handle obtained in section 3.2.3.

  • The dwFilter parameter set to the values CLUSTER_CHANGE_GROUP_ADDED and CLUSTER_CHANGE_GROUP_DELETED logically OR'd together (0x00006000).

  • The dwNotifyKey parameter set to the address of the filter block created for this registration request.

The caller next registers an event filter with the client that will cause the server to provide an indication each time "Resource1" changes state. The client creates an event filter data structure, initializes it with the caller supplied data, and links it to the notification port data structure. The client calls ApiAddNotifyResource (section 3.1.4.1.61 for protocol version 2, or 3.1.4.2.61 for protocol version 3) with the following:

  • The hNotify parameter set to the HNOTIFY_RPC context handle obtained from the previous ApiCreateNotify call.

  • The hResource parameter set to the HRES_RPC context handle obtained from the previous ApiOpenResource call.

  • The dwFilter parameter set to the value CLUSTER_CHANGE_RESOURCE_STATE (0x00000100).

  • The dwNotifyKey parameter set to the address of the filter block created for this registration request.

  • The dwStateSequence parameter set to the address of the StateSequence field in the event filter data structure.

Externally, another client has made a connection to the cluster and obtained an HGROUP_RPC context handle for a group named "Group1" by calling the ApiOpenGroup (section 3.1.4.1.42 for protocol version 2, or 3.1.4.2.42 for protocol version 3) method; this client then calls ApiDeleteGroup (section 3.1.4.1.44 for protocol version 2, or 3.1.4.2.44 for protocol version 3) using this context handle. The server responds by removing the group from the cluster configuration and generates an internal event indicating that "Group1" has been deleted. The server's notification port mechanism allocates an indication structure with the event type set to CLUSTER_CHANGE_GROUP_DELETED (0x00002000) and the object name set to "Group1" and posts it to all notification ports that have indicated an interest in this type of event.

The server thread representing the client's port service thread dequeues the indication from the server queue and returns the data in the indication to the client via ApiGetNotify parameters:

  • The dwNotifyKey parameter is set to the address of the client-side event filter data structure that was registered in the previous ApiAddNotifyCluster call.

  • The dwFilter parameter is set to the event type: CLUSTER_CHANGE_GROUP_DELETED (0x00002000).

  • The dwStateSequence is set to the current state sequence number of this group.

  • The Name parameter contains the name of the object ("Group1") as a Unicode string.

The port service thread allocates a client-side event indication structure and sets its values to the same event type and object name but sets the caller's context value in the structure instead of the context value returned by ApiGetNotify. The client port service thread queues this structure to the client-side queue and calls ApiGetNotify to wait for another indication.

A resource on which "Resource1" is dependent has failed and due to the server's restart policy, "Resource1" is taken offline and then returned to the online state. The server generates an internal event indicating that "Resource1" is in the ClusterResourceOffline state. The server's notification port mechanism allocates an indication structure with the type set to CLUSTER_CHANGE_RESOURCE_STATE (0x00000100) and the object name set to "Resource1" and posts it to all notification ports that have indicated an interest in this type of event.

The server thread representing the client's port service thread dequeues the indication from the server queue and returns the data in the indication to the client via ApiGetNotify parameters;

  • The dwNotifyKey parameter is set to address of the client-side event filter data structure that was registered in the previous ApiAddNotifyResource call.

  • The dwFilter parameter is set to the event type: CLUSTER_CHANGE_RESOURCE_STATE (0x00000100).

  • The dwStateSequence is set to the current state sequence number of this resource.

  • The Name parameter contains the name of the object ("Resource1") as a Unicode string.

The port service thread allocates a client-side event indication structure and sets its values to the same event type and object name but sets the caller's context value in the structure instead of the context value returned by ApiGetNotify. The ApiGetNotify thread queues this structure to the client-side queue and calls ApiGetNotify to wait for another indication.

When "Resource1" reaches the ClusterResourceOnline state, a similar internal event is generated and the server and client go through the same set of steps in which the online state change indication is delivered to the client-side queue, ready for consumption by the client's callers.