---
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();
    ```

