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

com.hazelcast.spi.impl.eventservice.impl.EventServiceSegment Maven / Gradle / Ivy

There is a newer version: 3.9.3
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.spi.impl.eventservice.impl;

import com.hazelcast.internal.metrics.Probe;
import com.hazelcast.nio.Address;
import com.hazelcast.spi.EventFilter;
import com.hazelcast.spi.ListenerWrapperEventFilter;
import com.hazelcast.spi.NotifiableEventListener;
import com.hazelcast.util.ConcurrencyUtil;
import com.hazelcast.util.ConstructorFunction;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

public class EventServiceSegment {

    private final String serviceName;
    private final S service;

    private final ConcurrentMap> registrations
            = new ConcurrentHashMap>();

    @Probe(name = "listenerCount")
    private final ConcurrentMap registrationIdMap = new ConcurrentHashMap();

    @Probe(name = "publicationCount")
    private final AtomicLong totalPublishes = new AtomicLong();

    public EventServiceSegment(String serviceName, S service) {
        this.serviceName = serviceName;
        this.service = service;
    }

    private void pingNotifiableEventListener(String topic, Registration registration, boolean register) {
        Object listener = registration.getListener();
        if (!(listener instanceof NotifiableEventListener)) {
            EventFilter filter = registration.getFilter();
            if (filter instanceof ListenerWrapperEventFilter) {
                listener = ((ListenerWrapperEventFilter) filter).getListener();
            }
        }
        pingNotifiableEventListenerInternal(listener, topic, registration, register);
        pingNotifiableEventListenerInternal(service, topic, registration, register);

    }

    private void pingNotifiableEventListenerInternal(Object object, String topic, Registration registration, boolean register) {
        if (!(object instanceof NotifiableEventListener)) {
            return;
        }

        NotifiableEventListener notifiableEventListener = ((NotifiableEventListener) object);
        if (register) {
            notifiableEventListener.onRegister(service, serviceName, topic, registration);
        } else {
            notifiableEventListener.onDeregister(service, serviceName, topic, registration);
        }
    }

    public Collection getRegistrations(String topic, boolean forceCreate) {
        Collection listenerList = registrations.get(topic);
        if (listenerList == null && forceCreate) {
            ConstructorFunction> func
                    = new ConstructorFunction>() {
                public Collection createNew(String key) {
                    return Collections.newSetFromMap(new ConcurrentHashMap());
                }
            };
            return ConcurrencyUtil.getOrPutIfAbsent(registrations, topic, func);
        }
        return listenerList;
    }

    public ConcurrentMap getRegistrationIdMap() {
        return registrationIdMap;
    }

    public boolean addRegistration(String topic, Registration registration) {
        final Collection registrations = getRegistrations(topic, true);
        if (registrations.add(registration)) {
            registrationIdMap.put(registration.getId(), registration);
            pingNotifiableEventListener(topic, registration, true);
            return true;
        }
        return false;
    }

    public Registration removeRegistration(String topic, String id) {
        final Registration registration = registrationIdMap.remove(id);
        if (registration != null) {
            final Collection all = registrations.get(topic);
            if (all != null) {
                all.remove(registration);
            }
            pingNotifiableEventListener(topic, registration, false);
        }
        return registration;
    }

    void removeRegistrations(String topic) {
        final Collection all = registrations.remove(topic);
        if (all != null) {
            for (Registration reg : all) {
                registrationIdMap.remove(reg.getId());
                pingNotifiableEventListener(topic, reg, false);
            }
        }
    }

    void clear() {
        for (Collection all : registrations.values()) {
            Iterator iter = all.iterator();
            while (iter.hasNext()) {
                Registration reg = iter.next();
                iter.remove();
                registrationIdMap.remove(reg.getId());
                pingNotifiableEventListener(reg.getTopic(), reg, false);
            }
        }
    }

    void onMemberLeft(Address address) {
        for (Collection all : registrations.values()) {
            Iterator iter = all.iterator();
            while (iter.hasNext()) {
                Registration reg = iter.next();
                if (address.equals(reg.getSubscriber())) {
                    iter.remove();
                    registrationIdMap.remove(reg.getId());
                    pingNotifiableEventListener(reg.getTopic(), reg, false);
                }
            }
        }
    }

    long incrementPublish() {
        return totalPublishes.incrementAndGet();
    }

    boolean hasRegistration(String topic) {
        Collection topicRegistrations = registrations.get(topic);
        return !(topicRegistrations == null || topicRegistrations.isEmpty());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy