All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.atomix.resource.Resource Maven / Gradle / Ivy

There is a newer version: 1.0.8
Show newest version
/*
 * Copyright 2015 the original author or authors.
 *
 * Licensed 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
 */
package io.atomix.resource;

import io.atomix.catalyst.concurrent.Listener;
import io.atomix.catalyst.concurrent.ThreadContext;
import io.atomix.catalyst.serializer.Serializer;
import io.atomix.catalyst.util.Managed;
import io.atomix.copycat.Command;
import io.atomix.copycat.Query;
import io.atomix.copycat.session.Session;

import java.io.Serializable;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

/**
 * Base class for fault-tolerant stateful distributed objects.
 * 

* Resources are stateful distributed objects that run across a set of {@link io.atomix.copycat.server.CopycatServer}s * in a cluster. *

* Resources can be created either as standalone {@link io.atomix.copycat.server.StateMachine}s in * a typical Copycat cluster or as {@code Atomix} resources. Operations on the resource are translated into * {@link Command}s and {@link Query}s which are submitted to the cluster where they're logged and * replicated. *

* Resource implementations must be annotated with the {@link ResourceTypeInfo} annotation to indicate the * {@link ResourceStateMachine} to be used by the Atomix resource manager. Additionally, resources must be * registered via the {@code ServiceLoader} pattern in a file at {@code META-INF/services/io.atomix.resource.Resource} * on the class path. The resource registration allows the Atomix resource manager to locate and load the resource * state machine on each server in the cluster. * * @param resource type * @author Jordan Halterman */ public interface Resource> extends Managed { /** * Base class for cluster-wide resource configurations. *

* Resource configurations control options specific to the resource's replicated {@link ResourceStateMachine}. * These options might include a maximum collection size or the order of values in a multi-map. */ class Config extends Properties implements Serializable { public Config() { } public Config(Properties defaults) { super(); for (String property : defaults.stringPropertyNames()) { setProperty(property, defaults.getProperty(property)); } } } /** * Base class for local resource options. *

* Options are configurations that are specific to a local resource instance. The first time a resource * is created by a client, the client may provide {@code Options} specifying the behavior of the resource * instance. Those initial options configure the behavior of the resource instance on the local node only. */ class Options extends Properties { public Options() { } public Options(Properties defaults) { super(defaults); } } /** * Resource event type. *

* An event type should be created for each distinct {@link Event} supported by a resource type. * The event type provides an {@link #id()} that is used internally by Atomix to invoke event * handlers within the resource client. */ interface EventType { /** * Returns the event type ID. *

* The event type ID is used to identify event types when published from the server state * machine to the client. Event type IDs must be unique within a resource type. * * @return The event type ID. This must be unique within a resource type. */ int id(); } /** * Resource event interface. *

* Resources should implement this interface for event messages sent from {@link ResourceStateMachine}s * to resource clients. Each event type should be associated with a unique {@link EventType} that indicates * the event identifier. */ interface Event { /** * Returns the resource event type. *

* The event type should be unique to the specific event as it's used as an event identifier. * * @return The resource event type. */ EventType type(); } /** * Resource session state constants. *

* The resource state is indicative of the resource's ability to communicate with the cluster within the * context of the underlying {@link Session}. In some cases, resource state changes may be indicative of a * loss of guarantees. Users of the resource should {@link Resource#onStateChange(Consumer) watch} the state * of a resource to determine when guarantees are lost and react to changes in the resource's ability to communicate * with the cluster. *

*

   *   {@code
   *   resource.onStateChange(state -> {
   *     switch (state) {
   *       case OPEN:
   *         // The resource is healthy
   *         break;
   *       case SUSPENDED:
   *         // The resource is unhealthy and operations may be unsafe
   *         break;
   *       case CLOSED:
   *         // The resource has been closed and pending operations have failed
   *         break;
   *     }
   *   });
   *   }
   * 
* So long as the resource is in the {@link #CONNECTED} state, all guarantees with respect to reads and writes will * be maintained, and a loss of the {@code CONNECTED} state may indicate a loss of linearizability. See the specific * states for more info. *

* Reference resource documentation for implications of the various states on specific resources. */ enum State { /** * Indicates that the resource is connected and operating normally. *

* The {@code CONNECTED} state indicates that the resource is healthy and operating normally. Operations submitted * and completed while the resource is in this state are guaranteed to adhere to the configured consistency level. */ CONNECTED, /** * Indicates that the resource is suspended and its session may or may not be expired. *

* The {@code SUSPENDED} state is indicative of an inability to communicate with the cluster within the context of * the underlying client's {@link Session}. Operations performed on resources in this state should be considered * unsafe. An operation performed on a {@link #CONNECTED} resource that transitions to the {@code SUSPENDED} state * prior to the operation's completion may be committed multiple times in the event that the underlying session * is ultimately {@link Session.State#EXPIRED expired}, thus breaking linearizability. Additionally, state machines * may see the session expire while the resource is in this state. *

* A resource that is in the {@code SUSPENDED} state may transition back to {@link #CONNECTED} once its underlying * session is recovered. However, operations not yet completed prior to the resource's recovery may lose linearizability * guarantees. If an operation is submitted while a resource is in the {@link #CONNECTED} state and the resource loses * and recovers its session, the operation may be applied to the resource's state more than once. Operations completed * across sessions are guaranteed to be performed at-least-once only. */ SUSPENDED, /** * Indicates that the resource is closed. *

* A resource may transition to this state as a result of an expired session or an explicit {@link Resource#close() close} * by the user or a closure of the resource's underlying client. */ CLOSED } /** * Returns the resource type. * * @return The resource type. */ ResourceType type(); /** * Returns the resource serializer. * * @return The resource serializer. */ Serializer serializer(); /** * Returns the resource configuration. * * @return The resource configuration. */ Config config(); /** * Returns the resource options. * * @return The configured resource options. */ Options options(); /** * Returns the current resource state. *

* The resource's {@link State} is indicative of the resource's ability to communicate with the cluster at any given * time. Users of the resource should use the state to determine when guarantees may be lost. See the {@link State} * documentation for information on the specific states, and see resource implementation documentation for the * implications of different states on resource consistency. * * @return The current resource state. */ State state(); /** * Registers a resource state change listener. * * @param callback The callback to call when the resource state changes. * @return The state change listener. */ Listener onStateChange(Consumer callback); /** * Registers a listener which gets called after the resource recovery process * * @param callback The callback to call when the resource finishes recovery process. * @return The recovery listener. */ Listener onRecovery(Consumer callback); /** * Returns the resource thread context. * * @return The resource thread context. */ ThreadContext context(); /** * Opens the resource. *

* Once the resource is opened, the resource will be transitioned to the {@link State#CONNECTED} state * and the returned {@link CompletableFuture} will be completed. * * @return A completable future to be completed once the resource is opened. */ @Override @SuppressWarnings("unchecked") CompletableFuture open(); /** * Closes the resource. *

* Once the resource is closed, the resource will be transitioned to the {@link State#CLOSED} state and * the returned {@link CompletableFuture} will be completed. Thereafter, attempts to operate on the resource * will fail. * * @return A completable future to be completed once the resource is closed. */ @Override CompletableFuture close(); /** * Deletes the resource state. * * @return A completable future to be completed once the resource has been deleted. */ CompletableFuture delete(); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy