blob: 44dd74e9ff92fd47eb0127e866c468355adc9e90 [file] [log] [blame]
---
title: Continuous Queries
---
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
The C++ and .NET clients can initiate queries that run on the <%=vars.product_name%> cache server
and notify the client when the query results have changed. For details on the server-side setup for
continuous queries, see [How Continuous Querying Works](serverman/developing/continuous_querying/how_continuous_querying_works.html)
in the *<%=vars.product_name%> User Guide*.
## <a id="cq_main_features" ></a>Continuous Query Basics
Continuous querying provides the following features:
- **Standard <%=vars.product_name%> native client query syntax and semantics**. Continuous queries are expressed in the same language used for other native client queries. See [Remote Queries](remote-queries.html).
- **Standard <%=vars.product_name%> events-based management of CQ events**. The event handling used
to process CQ events is based on the standard <%=vars.product_name%> event handling framework.
- **Complete integration with the client/server architecture**. CQ functionality uses existing
server-to-client messaging mechanisms to send events. All tuning of your server-to-client
messaging also tunes the messaging of your CQ events. If your system is configured for high
availability then your CQs are highly available, with seamless failover provided in case of
server failure (see [High Availability for Client-to-Server Communication](preserving-data/high-availability-client-server.html)).
If your clients are durable, you can also define any of your CQs as durable (see [Durable Client Messaging](preserving-data/durable-client-messaging.html)).
- **Interest criteria based on data values**. Continuous queries are run against the region's entry values.
Compare this to register interest by reviewing [Registering Interest for Entries](regions/registering-interest-for-entries.html).
- **Active query execution**. Once initialized, the queries operate on new events. Events that change the query result are sent to the client immediately.
## <a id="cq_api"></a>Typical Continuous Query Lifecycle
1. 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.
2. The client initiates 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 server remotely evaluates the query string, and optionally returns the results to the client. `CqQuery execute*` methods include:
- `CqQuery.Execute()`
- `CqQuery.ExecuteWithInitialResults()`
1. A CQ Listener waits for events. When it receives events, it takes action accordingly with the data in the CqEvent.
3. 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.
## <a id="ExecutingACQ"></a>Executing a Continuous Query from the Client
The essential steps to create and execute a continuous query are:
1. Create an instance of the `QueryService` class. If you are using the pool API (recommended), you should obtain the `QueryService` from the pool.
1. Define a CQ Listener (an `ICqListener`) to field events sent from the server.
1. Use one of the `CqQuery execute*` methods to submit the query string to the cache server.
1. The server remotely evaluates the query string, then monitors those results and notifies the client if they change.
1. The client listens for changes that match the query predicate.
1. Iterate through the returned objects.
1. When finished, close down the continuous query.
### <a id="DotNetCQExample"></a>.NET Continuous Query Example
These C# code excerpts are from the `examples\dotnet\continuousquery` example included in your client
distribution. See the example for full context.
Following the steps listed above,
1. Create a query service:
```
var queryService = pool.GetQueryService();
```
1. Define an ICqListener:
```
public class MyCqListener<TKey, TResult> : ICqListener<TKey, TResult>
{
```
1. Create an instance of your ICqListener and insert it into a CQ attributes object:
```
var cqListener = new MyCqListener<string, Order>();
var cqAttributesFactory = new CqAttributesFactory<string, Order>();
cqAttributesFactory.AddCqListener(cqListener);
var cqAttributes = cqAttributesFactory.Create();
```
1. Create a Continuous Query using the query service and the CQ attributes:
```
var query = queryService.NewCq("MyCq", "SELECT * FROM /example_orderobject WHERE quantity > 30", cqAttributes, false);
```
1. Execute the query:
```
query.Execute();
```
1. Wait for events and do something with them.
```
/* Excerpt from the CqListener */
/* Determine Operation Type */
switch (ev.getQueryOperation())
{
case CqOperation.OP_TYPE_CREATE:
operationType = "CREATE";
break;
case CqOperation.OP_TYPE_UPDATE:
operationType = "UPDATE";
break;
case CqOperation.OP_TYPE_DESTROY:
operationType = "DESTROY";
break;
default:
break;
}
...
/* Take action based on OP Type */
```
1. When finished, close up shop.
```
query.Execute();
... (respond to events as they arrive)
query.Stop();
query.Close();
cache.Close();
```