---
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 [Highly Available Client/Server Event Messaging](/serverman/developing/events/ha_event_messaging_whats_next.html)). 
If your clients are durable, you can also define any of your CQs as durable (see [Implementing Durable Client/Server Messaging](/serverman/developing/events/implementing_durable_client_server_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 (a `CqListener`) 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="CppCQExample"></a>C++ Continuous Query Example

These C++ code excerpts are from the `examples/cpp/continuousquery` example included in your client
distribution. See the example for full context.

Following the steps listed above,

1. Create a query service:

    ```
    auto queryService = pool->getQueryService();
    ```

1. Define a CqListener:

    ```
    class MyCqListener : public CqListener {
    ```

1. Create an instance of your CqListener and insert it into a CQ attributes object:

    ```
    CqAttributesFactory cqFactory;

    auto cqListener = std::make_shared<MyCqListener>();

    cqFactory.addCqListener(cqListener);
    auto cqAttributes = cqFactory.create();
    ```

1. Create a Continuous Query using the query service and the CQ attributes:

    ```
      auto query = queryService->newCq(
	  "MyCq", "SELECT * FROM /custom_orders c WHERE c.quantity > 30",
	  cqAttributes);
    ```

1. Execute the query:

    ```
    query->execute();
    ```

1. Wait for events and do something with them.

    ```
	/* Excerpt from the CqListener */

	/* Determine Operation Type */
	switch (cqEvent.getQueryOperation()) {
	case CqOperation::OP_TYPE_CREATE:
	  opStr = "CREATE";
	  break;
	case CqOperation::OP_TYPE_UPDATE:
	  opStr = "UPDATE";
	  break;
	case CqOperation::OP_TYPE_DESTROY:
	  opStr = "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();
    ```
