How Continuous Querying Works
How Continuous Querying Works
C++ and C# .NET clients register interest in events using simple query expressions. Events are sent to client listeners that you can program to do whatever your application requires.
Overview of CQ Operations
You subscribe to server-side events using SQL-type query filtering. The native client sends a query to the server side for execution and receives the events that satisfy the criteria.
SELECT * FROM /tradeOrder t WHERE t.price > 100.00
When the CQ is running, the server sends the client all new events that affect the results of the query. On the native client side, listeners programmed by you receive and process incoming events. For the example query on /tradeOrder, you might program a listener to push events to a GUI where higher-priced orders are displayed. CQ event delivery uses the client/server subscription framework described in Client to Server Connection Process.
CQs do not update the native client region. This is in contrast to other server-to-client messaging, like the updates sent to satisfy interest registration and responses to get requests from the client. CQs are notification tools for the CQ listeners, which can be programmed in any way your application requires.
When a CQ is running against a server region, each entry event is evaluated against the CQ query by the thread that updates the server cache. If either the old or the new entry value satisfies the query, the thread puts a CqEvent in the client's queue. The CqEvent contains information from the original cache event, plus information specific to the CQ's execution. Once received by the client, the CqEvent is passed to the onEvent method of all CqListeners defined for the CQ.
Logical Architecture and Data Flow
Clients can execute any number of CQs, with each CQ given any number of listeners. This figure shows the logical architecture of continuous querying.
The next figure shows the typical CQ data flow when entries are updated in the server cache. A description of the data flow follows, along with a description of CQ state and life cycle.
- Entry events come to the server's cache from any source: the server or its peers, distribution from remote sites, or updates from a client.
- For each event, the server's CQ executor framework checks for a match with the CQs it has running.
- If the old or new entry value satisfies
a CQ query, a CQ event is sent to the CQ's listeners on the client side. Each
listener for the CQ gets the event. In the preceding figure:
- Both new and old prices for entry X satisfy the CQ query, so that event is sent indicating an update to the query results.
- The old price for entry Y satisfied the query, so it was part of the query results. The invalidation of entry Y means that it does not satisfy the query. Because of this, the event is sent indicating that it is destroyed in the query results.
- The price for the newly created entry Z does not satisfy the query, so no event is sent.
The region operations do not translate directly to specific query operations, and the query operations do not specifically describe the region events. Instead, each query operation describes how its corresponding region event affects the query results. For more information, see CqEvent Object.
State and Life CycleA CQ has three possible states that can be accessed from the client by calling CqQuery.getState.
- STOPPED. The CQ has been created but not yet executed, or it has been explicitly stopped from executing. The stopped CQ uses system resources. You start or restart the CQ by calling the execute method on CqQuery.
- RUNNING. The CQ is being executed on the server for all events in the region referenced by the query. Results are sent to all client listeners associated with the CqQuery.
- CLOSED. The CQ is closed and is not using system resources. Invoking an execute or stop method on closed CqQuery throws an exception.
- The client creates the CQ. This sets up everything for running the query and provides the client with a CqQuery object, but does not execute the CQ. At this point, the query is in a STOPPED state, ready to be closed or run.
- The client runs the CQ with an API call to one of the CqQuery execute* methods. This puts the query into a RUNNING state on the client and on the server.
- The CQ is closed by a client call to CqQuery.close. This de-allocates all resources in use for the CQ on the client and server. At this point, the cycle could begin again with the creation of a new CqQuery instance.