# Evaluator Server

The `EvaluatorServer` object is responsible for coordinating the estimation of physical property data sets as requested by evaluator clients. Its primary responsibilities are to:

- recieve incoming requests from an evaluator clients to either estimate a dataset of properties, or to query the status of a previous request.

- request that each specified calculation layers attempt to estimate the data set of properties, cascading unestimated properties through the different layers.

An `EvaluatorServer` must be created with an accompanying calculation backend which will be responsible for distributing any calculations launched by the different calculation layers:

    with DaskLocalCluster() as calculation_backend:

        evaluator_server = EvaluatorServer(calculation_backend)
        evaluator_server.start()

It may also be optionally created using a specific storage backend if the default `LocalFileStorage` is not sufficient:

    with DaskLocalCluster() as calculation_backend:

        storage_backend = LocalFileStorage()

        evaluator_server = EvaluatorServer(calculation_backend, storage_backend)
        evaluator_server.start()

By default the server will run synchronously until it is killed, however it may also be run asynchronously such that it can be interacted with directly by a client in the same script:

    with DaskLocalCluster() as calculation_backend:

        with EvaluatorServer(calculation_backend) as evaluator_server:

            # Specify the data set.
            data_set = PhysicalPropertyDataSet()
            data_set.add_properties(...)

            # Specify the force field source.
            force_field = SmirnoffForceFieldSource.from_path("openff-1.0.0.offxml")

            # Request the estimation of the data set.
            request, errors = evaluator_client.request_estimate(data_set,force_field)
            # Wait for the results.
            results = request.results(synchronous=True)

## Estimation Batches

When a server recieves a request from a client, it will attempt to split the requested set of properties into smaller batches, represented by the `Batch` object. The server is currently only able to mark entire batches of estimated properties as being completed, as opposed to individual properties.

Currently the server supports two ways of batching properties:

- `SameComponents`: All properties measured for the substance containing the same components will be batched together. As an example, the density of a 80:20 and a 20:80 mix of ethanol and water would be batched together, but the density of pure ethanol and the density of pure water would be placed into separate batches.

- `SharedComponents`: All properties measured for substances containing at least one common component will be batched together. As an example, the densities of 80:20 and 20:80 mixtures of ethanol and water, and the pure densities of ethanol and water would be batched together.

The mode of batching is set by the client using the `batch_mode` attribute of the request options.