При работе в распределенной среде часто необходимо иметь согласованное локальное состояние для каждого узла сетки, которое повторно используется при выполнении различных заданий. Например, что, если нескольким заданиям для выполнения требуется пул соединений с базой данных — как они получают этот пул соединений, который будет инициализирован один раз, а затем повторно использован всеми заданиями, работающими на одном узле сетки? По сути, вы можете думать об этом как о одноэлементном сервисе для каждого узла сетки, но идея не ограничивается только сервисами, это может быть просто обычный Java-бин, содержащий некоторое состояние, которое будет совместно использоваться всеми заданиями, выполняющимися на одном узле сетки. ,
В
версиях GridGain 2.x и более ранних версиях этот подход обрабатывался с помощью
аннотации @GridUserResource для аннотирования полей в
GridTask или
Классы GridJob для указания одноэлементных бинов . Однако этот подход зависит от
GridDeploymentMode конфигурации , и для
ИЗОЛИРОВАННОЕ или
ЧАСТНОЕ режимов развертывания, ресурс может быть инициализирован несколько раз, один раз в
GridTask . Это заставляло пользователей использовать различные хаки в их логике и, как правило, было не очень удобно использовать.
Начиная с GridGain 3.0,
было представлено локальное хранилище GridNodeLocal для каждого узла сетки. Имя было заимствовано из
класса ThreadLocal в Java, потому что точно так же, как
ThreadLocal обеспечивает уникальное пространство для каждого потока в Java,
GridNodeLocalпредоставляет уникальное пространство для каждой сетки в GridGain.
GridNodeLocal реализует
интерфейс java.util.concurrent.ConcurrentMap и абсолютно не блокируется. Фактически, он просто расширяет
реализацию java.util.concurrent.ConcurrentHashMap и, следовательно, наследует все доступные там методы.
Вот пример того, как GridNodeLocal можно использовать для создания какого- то
отдельного пользовательского однотонного сервиса из простого задания GridGain:
final Grid grid = G.start(..);
// Execute runnable job on some remote grid node.
grid.run(BALANCE, new Runnable() {
public void run() {
GridNodeLocal<String, MySingleton> nodeLocal = grid.nodeLocal();
// 1. Check if f someone already created our singleton service.
MySingleton service = nodeLocal.get("myservice");
if (service == null) {
// 2. Create new singleton service.
MySingleton other =
nodeLocal.putIfAbsent("myservice", service = new MySingleton(..));
if (other != null)
service = other;
}
// Perform operations with our singleton service.
...
}
});
С http://gridgain.blogspot.com/2011/08/clever-singletons-on-grid.html