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

com.aerospike.client.async.AsyncConnector Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2012-2023 Aerospike, Inc.
 *
 * Portions may be licensed to Aerospike, Inc. under one or more contributor
 * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
 *
 * 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.aerospike.client.async;

import java.util.concurrent.TimeUnit;

import com.aerospike.client.AerospikeException;
import com.aerospike.client.Log;
import com.aerospike.client.async.HashedWheelTimer.HashedWheelTimeout;
import com.aerospike.client.cluster.Cluster;
import com.aerospike.client.cluster.Node;
import com.aerospike.client.util.Util;

/**
 * Create async connection and place in connection pool.
 * Used for min connections functionality.
 */
public abstract class AsyncConnector implements Runnable, TimerTask {

	final EventLoopBase eventLoopBase;
	final EventState eventState;
	final Cluster cluster;
	final Node node;
	final AsyncConnector.Listener listener;
	final HashedWheelTimeout timeoutTask;
	int state;

	AsyncConnector(EventLoopBase eventLoopBase, Cluster cluster, Node node, AsyncConnector.Listener listener) {
		this.eventLoopBase = eventLoopBase;
		this.eventState = cluster.eventState[eventLoopBase.index];
		this.cluster = cluster;
		this.node = node;
		this.listener = listener;
		this.timeoutTask = new HashedWheelTimeout(this);
	}

	public final boolean execute() {
		if (! node.reserveAsyncConnectionSlot(eventLoopBase.index)) {
			return false;
		}

		try {
			if (eventState.errors < 5) {
				run();
			}
			else {
				// Avoid recursive error stack overflow by placing request at end of queue.
				eventLoopBase.execute(this);
			}
			return true;
		}
		catch (Throwable e) {
			Log.warn("Failed to create conn: " + Util.getErrorMessage(e));
			node.decrAsyncConnection(eventLoopBase.index);
			return false;
		}
	}

	@Override
	public void run() {
		try {
			long deadline = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(cluster.connectTimeout);
			eventLoopBase.timer.addTimeout(timeoutTask, deadline);

			createConnection();
			eventState.errors = 0;
		}
		catch (AerospikeException ae) {
			eventState.errors++;
			fail(ae);
		}
		catch (Throwable e) {
			eventState.errors++;
			fail(new AerospikeException(e));
		}
	}

	@Override
	public final void timeout() {
		fail(new AerospikeException.Timeout(node, cluster.connectTimeout, cluster.connectTimeout, cluster.connectTimeout));
	}

	final void success() {
		if (state == AsyncCommand.COMPLETE) {
			return;
		}

		close();

		if (addConnection()) {
			try {
				listener.onSuccess(this);
			}
			catch (Throwable e) {
				Log.error("onSuccess() error: " + Util.getErrorMessage(e));
			}
		}
		else {
			try {
				listener.onFailure();
			}
			catch (Throwable e) {
				Log.error("onFailure() error: " + Util.getErrorMessage(e));
			}
		}
	}

	final void fail(AerospikeException ae) {
		if (state == AsyncCommand.COMPLETE) {
			return;
		}

		close();
		closeConnection();

		try {
			listener.onFailure(ae);
		}
		catch (Throwable e) {
			Log.error("onFailure() error: " + Util.getErrorMessage(e));
		}
	}

	private final void close() {
		timeoutTask.cancel();
		state = AsyncCommand.COMPLETE;
	}

	abstract void createConnection();
	abstract boolean addConnection();
	abstract void closeConnection();

	interface Listener {
		void onSuccess(AsyncConnector ac);
		void onFailure(AerospikeException ae);
		void onFailure();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy