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

org.jetlang.channels.KeyedBatchSubscriber Maven / Gradle / Ivy

Go to download

Jetlang provides a high performance java threading library. It is a complement to the java.util.concurrent package introduced in 1.5 and should be used for message based concurrency similar to event based actors in Scala.

There is a newer version: 0.2.23
Show newest version
package org.jetlang.channels;

import org.jetlang.core.Callback;
import org.jetlang.core.Filter;
import org.jetlang.fibers.Fiber;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Channel subscription that drops duplicates based upon a key.
 */
public class KeyedBatchSubscriber extends BaseSubscription {
    private final Object _batchLock = new Object();

    private final Fiber _context;
    private final Callback> _target;
    private final int _flushIntervalInMs;
    private final TimeUnit _timeUnit;
    private final Converter _keyResolver;

    private Map _pending = null;
    private final Runnable _flushRunner;

    public KeyedBatchSubscriber(Fiber context,
                                Callback> target,
                                Filter filter,
                                int flushIntervalInMs, TimeUnit timeUnit,
                                Converter keyResolver) {
        super(context, filter);
        _keyResolver = keyResolver;
        _context = context;
        _target = target;
        _flushIntervalInMs = flushIntervalInMs;
        _timeUnit = timeUnit;
        _flushRunner = new Runnable() {
            public void run() {
                flush();
            }

            @Override
            public String toString() {
                return "Flushing " + KeyedBatchSubscriber.this + " via " +  _target.toString();
            }
        };
    }

    public KeyedBatchSubscriber(Fiber context, Callback> target,
                                int flushIntervalInMs, TimeUnit timeUnit,
                                Converter keyResolver) {
        this(context, target, null, flushIntervalInMs, timeUnit, keyResolver);
    }

    /**
     * Message received and batched on producer thread.
     */
    @Override
    protected void onMessageOnProducerThread(T msg) {
        synchronized (_batchLock) {
            K key = _keyResolver.convert(msg);
            if (_pending == null) {
                _pending = new HashMap<>();
                _context.schedule(_flushRunner, _flushIntervalInMs, _timeUnit);
            }
            _pending.put(key, msg);
        }
    }


    /**
     * Flushes events on fiber thread
     */
    private void flush() {
        Map toReturn = clearPending();
        if (toReturn != null) {
            _target.onMessage(toReturn);
        }
    }

    private Map clearPending() {
        synchronized (_batchLock) {
            if (_pending == null || _pending.isEmpty()) {
                _pending = null;
                return null;
            }
            Map toReturn = _pending;
            _pending = null;
            return toReturn;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy