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

org.jetlang.channels.LastSubscriber 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.concurrent.TimeUnit;

/**
 * Subscribes to last event received on the channel. If consuming thread cannot
 * process events as fast as they arrive, then older events will be dropped in favor
 * of most recent.  Flush interval determines rate at which events are processes. If interval is less than 1, then
 * events will be delivered as fast as consuming thread can handle them.
 */
public class LastSubscriber extends BaseSubscription {
    private final Object _lock = new Object();

    private final Fiber _context;
    private final Callback _target;
    private final int _flushIntervalInMs;
    private final TimeUnit _timeUnit;

    private boolean _flushPending;
    private T _pending;
    private final Runnable _flushRunnable;

    public LastSubscriber(Fiber context, Callback target, Filter filter,
                          int flushInterval, TimeUnit timeUnit) {
        super(context, filter);
        _context = context;
        _target = target;
        _flushIntervalInMs = flushInterval;
        _timeUnit = timeUnit;
        _flushRunnable = new Runnable() {
            public void run() {
                flush();
            }

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

    public LastSubscriber(Fiber context, Callback target,
                          int flushInterval, TimeUnit timeUnit) {
        this(context, target, null, flushInterval, timeUnit);
    }

    @Override
    protected void onMessageOnProducerThread(T msg) {
        synchronized (_lock) {
            if (!_flushPending) {
                _flushPending = true;

                if (_flushIntervalInMs < 1) {
                    _context.execute(_flushRunnable);
                } else {
                    _context.schedule(_flushRunnable, _flushIntervalInMs, _timeUnit);
                }
            }
            _pending = msg;
        }
    }

    private void flush() {
        T toReturn = clearPending();
        _target.onMessage(toReturn);
    }

    private T clearPending() {
        synchronized (_lock) {
            _flushPending = false;
            return _pending;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy