Search in sources :

Example 1 with SizeLimitExceededException

use of com.linkedin.r2.SizeLimitExceededException in project rest.li by linkedin.

the class AsyncSharedPoolImpl method get.

@Override
public Cancellable get(Callback<T> callback) {
    ArgumentUtil.notNull(callback, "callback");
    final TimeTrackingCallback timeTrackingCallback = new TimeTrackingCallback(callback);
    final LinkedDeque.Node<Callback<T>> node;
    T item = null;
    boolean create = false;
    while (true) {
        final State state;
        synchronized (_lock) {
            state = _state;
            if (state == State.RUNNING) {
                item = _item.get();
                if (item == null) {
                    node = _waiters.size() < _maxWaiters ? _waiters.addLastNode(timeTrackingCallback) : null;
                    if (_isCreateInProgress) {
                        LOG.debug("{}: item creation is in progress", _name);
                    } else {
                        _isCreateInProgress = true;
                        create = true;
                    }
                    break;
                }
                _checkedOut++;
                _statsTracker.sampleMaxCheckedOut();
            }
        }
        if (state != State.RUNNING) {
            // Defer execution of the callback until we are out of the synchronized block
            timeTrackingCallback.onError(new IllegalStateException(_name + " is " + _state));
            return () -> false;
        }
        // through the item lifecycle before passing back to user callback
        if (_lifecycle.validateGet(item)) {
            timeTrackingCallback.onSuccess(item);
            return () -> false;
        }
        boolean disposed;
        synchronized (_lock) {
            // The connection has gone bad so we proceed to destroy it
            disposed = doDispose(item);
        }
        if (disposed) {
            doDestroy(item, BAD, () -> {
            });
        }
    }
    if (node == null) {
        // This is a recoverable exception. User can simply retry the failed get() operation.
        timeTrackingCallback.onError(new SizeLimitExceededException("AsyncPool " + _name + " reached maximum waiter size: " + _maxWaiters));
        return () -> false;
    }
    // The pool is currently empty we need to construct a new item
    if (create) {
        doCreate();
    }
    return () -> {
        synchronized (_lock) {
            return _waiters.removeNode(node) != null;
        }
    };
}
Also used : SizeLimitExceededException(com.linkedin.r2.SizeLimitExceededException) SimpleCallback(com.linkedin.common.callback.SimpleCallback) Callback(com.linkedin.common.callback.Callback) LinkedDeque(com.linkedin.r2.util.LinkedDeque)

Example 2 with SizeLimitExceededException

use of com.linkedin.r2.SizeLimitExceededException in project rest.li by linkedin.

the class AsyncPoolImpl method get.

@Override
public Cancellable get(final Callback<T> callback) {
    // getter needs to add to wait queue atomically with check for empty pool
    // putter needs to add to pool atomically with check for empty wait queue
    boolean create = false;
    boolean reject = false;
    final LinkedDeque.Node<Callback<T>> node;
    Callback<T> callbackWithTracking = new TimeTrackingCallback<>(callback);
    for (; ; ) {
        TimedObject<T> obj = null;
        final State state;
        synchronized (_lock) {
            state = _state;
            if (state == State.RUNNING) {
                if (_strategy == Strategy.LRU) {
                    obj = _idle.pollFirst();
                } else {
                    obj = _idle.pollLast();
                }
                if (obj == null) {
                    if (_waiters.size() < _maxWaiters) {
                        if (isWaiterTimeoutEnabled()) {
                            callbackWithTracking = new WaiterTimeoutCallback(callbackWithTracking);
                        }
                        // No objects available and the waiter list is not full; add to waiter list and break out of loop
                        node = _waiters.addLastNode(callbackWithTracking);
                        create = shouldCreate();
                    } else {
                        reject = true;
                        node = null;
                    }
                    break;
                }
            }
        }
        if (state != State.RUNNING) {
            // Defer execution of the callback until we are out of the synchronized block
            callbackWithTracking.onError(new IllegalStateException(_poolName + " is " + _state));
            return () -> false;
        }
        T rawObj = obj.get();
        if (_lifecycle.validateGet(rawObj)) {
            trc("dequeued an idle object");
            // Valid object; done
            synchronized (_lock) {
                _checkedOut++;
                _statsTracker.sampleMaxCheckedOut();
            }
            callbackWithTracking.onSuccess(rawObj);
            return () -> false;
        }
        // Invalid object, discard it and keep trying
        destroy(rawObj, true);
        trc("dequeued and disposed an invalid idle object");
    }
    if (reject) {
        // This is a recoverable exception. User can simply retry the failed get() operation.
        callbackWithTracking.onError(new SizeLimitExceededException("AsyncPool " + _poolName + " reached maximum waiter size: " + _maxWaiters));
        return () -> false;
    }
    trc("enqueued a waiter");
    if (create) {
        create();
    }
    return new Cancellable() {

        @Override
        public boolean cancel() {
            synchronized (_lock) {
                boolean cancelled = _waiters.removeNode(node) != null;
                if (cancelled) {
                    shutdownIfNeeded();
                }
                return cancelled;
            }
        }
    };
}
Also used : Cancellable(com.linkedin.r2.util.Cancellable) SizeLimitExceededException(com.linkedin.r2.SizeLimitExceededException) Callback(com.linkedin.common.callback.Callback) SimpleCallback(com.linkedin.common.callback.SimpleCallback) LinkedDeque(com.linkedin.r2.util.LinkedDeque)

Aggregations

Callback (com.linkedin.common.callback.Callback)2 SimpleCallback (com.linkedin.common.callback.SimpleCallback)2 SizeLimitExceededException (com.linkedin.r2.SizeLimitExceededException)2 LinkedDeque (com.linkedin.r2.util.LinkedDeque)2 Cancellable (com.linkedin.r2.util.Cancellable)1