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

com.hazelcast.cache.impl.operation.CacheCreateConfigOperation Maven / Gradle / Ivy

There is a newer version: 5.4.0
Show newest version
/*
 * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
 *
 * 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 com.hazelcast.cache.impl.operation;

import com.hazelcast.cache.impl.CacheDataSerializerHook;
import com.hazelcast.cache.impl.ICacheService;
import com.hazelcast.config.CacheConfig;
import com.hazelcast.core.ExecutionCallback;
import com.hazelcast.core.Member;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.IdentifiedDataSerializable;
import com.hazelcast.spi.NodeEngine;
import com.hazelcast.spi.OperationService;
import com.hazelcast.spi.impl.AbstractNamedOperation;
import com.hazelcast.spi.impl.SimpleExecutionCallback;

import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Used to create cluster wide cache configuration.
 * 

This configuration is created using the following algorithm; *

    *
  • Find partition id using the distributed object name of cache as a key.
  • *
  • Send the CacheCreateConfigOperation operation to the calculated partition which will force all * clusters to be single threaded.
  • *
  • {@link ICacheService#putCacheConfigIfAbsent(com.hazelcast.config.CacheConfig)} is called.
  • *

*

This operation's purpose is to pass the required parameters into * {@link ICacheService#putCacheConfigIfAbsent(com.hazelcast.config.CacheConfig)}.

*/ public class CacheCreateConfigOperation extends AbstractNamedOperation implements IdentifiedDataSerializable { private CacheConfig config; private boolean createAlsoOnOthers = true; private boolean ignoreLocal; private boolean returnsResponse = true; private transient Object response; public CacheCreateConfigOperation() { } public CacheCreateConfigOperation(CacheConfig config) { this(config, true); } public CacheCreateConfigOperation(CacheConfig config, boolean createAlsoOnOthers) { this(config, createAlsoOnOthers, false); } public CacheCreateConfigOperation(CacheConfig config, boolean createAlsoOnOthers, boolean ignoreLocal) { super(config.getNameWithPrefix()); this.config = config; this.createAlsoOnOthers = createAlsoOnOthers; this.ignoreLocal = ignoreLocal; } @Override public String getServiceName() { return ICacheService.SERVICE_NAME; } @Override public void run() throws Exception { ICacheService service = getService(); if (!ignoreLocal) { response = service.putCacheConfigIfAbsent(config); } if (createAlsoOnOthers) { NodeEngine nodeEngine = getNodeEngine(); Collection members = nodeEngine.getClusterService().getMembers(); int remoteNodeCount = members.size() - 1; if (remoteNodeCount > 0) { postponeReturnResponse(); ExecutionCallback callback = new CacheConfigCreateCallback(this, remoteNodeCount); OperationService operationService = nodeEngine.getOperationService(); for (Member member : members) { if (!member.localMember()) { CacheCreateConfigOperation op = new CacheCreateConfigOperation(config, false); operationService .createInvocationBuilder(ICacheService.SERVICE_NAME, op, member.getAddress()) .setExecutionCallback(callback) .invoke(); } } } } } private void postponeReturnResponse() { // If config already exists or it's local-only created then return response immediately. // Otherwise response will be sent after config is created on all members. returnsResponse = false; } @Override public void onExecutionFailure(Throwable e) { // Execution failed so we should enable `returnsResponse` flag to prevent waiting anymore returnsResponse = true; super.onExecutionFailure(e); } private static class CacheConfigCreateCallback extends SimpleExecutionCallback { final AtomicInteger counter; final CacheCreateConfigOperation operation; public CacheConfigCreateCallback(CacheCreateConfigOperation op, int count) { this.operation = op; this.counter = new AtomicInteger(count); } @Override public void notify(Object object) { if (counter.decrementAndGet() == 0) { operation.sendResponse(null); } } } @Override public Object getResponse() { return response; } @Override public boolean returnsResponse() { return returnsResponse; } @Override protected void writeInternal(ObjectDataOutput out) throws IOException { super.writeInternal(out); out.writeObject(config); out.writeBoolean(createAlsoOnOthers); out.writeBoolean(ignoreLocal); } @Override protected void readInternal(ObjectDataInput in) throws IOException { super.readInternal(in); config = in.readObject(); createAlsoOnOthers = in.readBoolean(); ignoreLocal = in.readBoolean(); } @Override public int getId() { return CacheDataSerializerHook.CREATE_CONFIG; } @Override public int getFactoryId() { return CacheDataSerializerHook.F_ID; } }