Creating PMI Handlers

The basic form of a PMI handler is a CacheEntryForEach handler. Inherit from CacheEntryForEach and register your class as an invocation event handler to accept PMI requests from clients.

Prerequisites

  • ScaleOut StateServer Pro license

Procedure

Note

This sample in its entirety is available on our GitHub Samples Repo.

  1. Determine the type parameters to use with your ForEach handler.

    • A PMI operation evaluates objects stored in a ScaleOut Cache. Caches in the library are strongly-typed, so invocation handlers are also strongly-typed.

    • This example analyzes a cache that tracks the most recent login date for an application’s users. The cache’s key type is a string (representing a User ID), and its value type is a long (representing a login time).

  2. Create a class that inherits from ForEach<TKey, TValue>.

    package com.scaleout.client.samples.compute;
    
    import com.scaleout.client.caching.CacheEntryForEachHandler;
    import com.scaleout.client.caching.OperationContext;
    
    public class FindInactiveUsersForEachHandler implements CacheEntryForEachHandler<String, Long, Void> {
            @Override
            public void evaluate(String key, OperationContext<String, Long, Void> operationContext) {
                    //
            }
    }
    
  3. Implement your custom evaluation code.

    • During a PMI operation, your Evaluate method will be called for every object in the ScaleOut cache.

    • Your method can read, modify, delete, or perform any needed cache operation. In this example, login times are retrieved to identify inactive users.

    // Use the cache in the PMI context to retrieve the object being evaluated:
    var readResponse = operationContext.getCache().read(key);
    if (readResponse.getStatus() == RequestStatus.ObjectNotFound)
    {
            System.out.println(key + " removed by another client during PMI operation.");
            return;
    }
    else if (readResponse.getStatus() != RequestStatus.ObjectRetrieved)
    {
            System.out.println("Unexpected error (" + readResponse.getStatus() + ") while reading key: " + key);
            return;
    }
    
    // Perform analysis:
    long lastLoginEpochMs = readResponse.getValue();
    long inactiveTimeMs = System.currentTimeMillis() - lastLoginEpochMs;
    if (inactiveTimeMs > Duration.ofDays(7).toMillis())
    {
            System.out.println(key + " inactive for {inactiveTime.TotalDays} days.");
    }
    
  4. At application startup, register the class as an invocation handler. If you are running your handler in an Invocation Grid, this code should be put in your project’s InvocationGridStartup.configure() method.

    Tip

    A PMI application can have multiple invocation handlers registered against multiple caches.

    package com.scaleout.client.samples.compute;
    
    import com.scaleout.client.GridConnectException;
    import com.scaleout.client.GridConnection;
    import com.scaleout.client.ServiceEvents;
    import com.scaleout.client.ServiceEventsException;
    import com.scaleout.client.caching.Cache;
    import com.scaleout.client.caching.CacheBuilder;
    
    import java.io.IOException;
    
    public class PMIHandlerSample {
        public static void main(String[] args) throws GridConnectException, ServiceEventsException, IOException {
            GridConnection connection = GridConnection.connect("bootstrapGateways=localhost");
            Cache<String, Long> cache = new CacheBuilder<String, Long>(connection, "PMISample", String.class)
                    .build();
    
            ServiceEvents.setForEachEventHandler(cache, "Find inactive users", new FindInactiveUsersForEachHandler());
            System.out.println("Waiting for events...");
            System.out.println("Press any key to exit.");
            System.in.read();
        }
    }
    
  5. Build your handler application and deploy it to all the servers in your farm that are running the ScaleOut service.

    • Once your handler app is running on all your ScaleOut hosts, you are ready to process PMI requests.