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

org.wildfly.clustering.session.infinispan.embedded.InfinispanSessionManager Maven / Gradle / Ivy

/*
 * Copyright The WildFly Authors
 * SPDX-License-Identifier: Apache-2.0
 */
package org.wildfly.clustering.session.infinispan.embedded;

import java.util.Set;
import java.util.concurrent.CompletionStage;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.infinispan.Cache;
import org.infinispan.configuration.cache.PersistenceConfiguration;
import org.infinispan.configuration.cache.StoreConfiguration;
import org.infinispan.context.Flag;
import org.wildfly.clustering.cache.CacheProperties;
import org.wildfly.clustering.cache.Key;
import org.wildfly.clustering.cache.batch.Batch;
import org.wildfly.clustering.cache.infinispan.embedded.distribution.Locality;
import org.wildfly.clustering.server.Registrar;
import org.wildfly.clustering.server.Registration;
import org.wildfly.clustering.server.expiration.ExpirationMetaData;
import org.wildfly.clustering.server.manager.IdentifierFactory;
import org.wildfly.clustering.server.scheduler.Scheduler;
import org.wildfly.clustering.session.ImmutableSession;
import org.wildfly.clustering.session.Session;
import org.wildfly.clustering.session.SessionManager;
import org.wildfly.clustering.session.SessionManagerConfiguration;
import org.wildfly.clustering.session.SessionStatistics;
import org.wildfly.clustering.session.cache.AbstractSessionManager;
import org.wildfly.clustering.session.cache.SessionFactory;
import org.wildfly.clustering.session.infinispan.embedded.metadata.SessionMetaDataKeyFilter;

/**
 * Generic session manager implementation - independent of cache mapping strategy.
 * @param  the session manager context type
 * @param  the meta-data value type
 * @param  the attributes value type
 * @param  the session context type
 * @author Paul Ferraro
 */
public class InfinispanSessionManager extends AbstractSessionManager {

	private final Supplier batcher;
	private final Cache, ?> cache;
	private final CacheProperties properties;
	private final IdentifierFactory identifierFactory;
	private final Scheduler expirationScheduler;
	private final Runnable startTask;
	private final Registrar> registrar;

	private volatile Registration registration;

	public InfinispanSessionManager(SessionManagerConfiguration configuration, InfinispanSessionManagerConfiguration infinispanConfiguration, SessionFactory factory) {
		super(configuration, infinispanConfiguration, factory, new Consumer<>() {
			@Override
			public void accept(ImmutableSession session) {
				if (session.isValid()) {
					infinispanConfiguration.getExpirationScheduler().schedule(session.getId(), session.getMetaData());
				}
			}
		});
		this.cache = infinispanConfiguration.getCache();
		this.properties = infinispanConfiguration.getCacheProperties();
		this.identifierFactory = infinispanConfiguration.getIdentifierFactory();
		this.batcher = infinispanConfiguration.getBatchFactory();
		this.expirationScheduler = infinispanConfiguration.getExpirationScheduler();
		this.registrar = infinispanConfiguration.getRegistrar();
		this.startTask = infinispanConfiguration.getStartTask();
	}

	@Override
	public void start() {
		this.registration = this.registrar.register(this);
		this.identifierFactory.start();
		this.startTask.run();
	}

	@Override
	public void stop() {
		if (!this.properties.isPersistent()) {
			PersistenceConfiguration persistence = this.cache.getCacheConfiguration().persistence();
			// Don't passivate sessions on stop if we will purge the store on startup
			if (persistence.passivation() && !persistence.stores().stream().allMatch(StoreConfiguration::purgeOnStartup)) {
				try (Stream> stream = this.cache.getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_CACHE_LOAD, Flag.SKIP_LOCKING).keySet().stream()) {
					stream.filter(SessionMetaDataKeyFilter.INSTANCE).forEach(this.cache::evict);
				}
			}
		}
		this.identifierFactory.stop();
		this.registration.close();
	}

	@Override
	public Supplier getBatchFactory() {
		return this.batcher;
	}

	@Override
	public Supplier getIdentifierFactory() {
		return this.identifierFactory;
	}

	@Override
	public CompletionStage> findSessionAsync(String id) {
		this.expirationScheduler.cancel(id);
		return super.findSessionAsync(id);
	}

	@Override
	public SessionStatistics getStatistics() {
		return this;
	}

	@Override
	public Set getActiveSessions() {
		// Omit remote sessions (i.e. when using DIST mode) as well as passivated sessions
		return this.getSessions(Flag.CACHE_MODE_LOCAL, Flag.SKIP_CACHE_LOAD);
	}

	@Override
	public Set getSessions() {
		// Omit remote sessions (i.e. when using DIST mode)
		return this.getSessions(Flag.CACHE_MODE_LOCAL);
	}

	private Set getSessions(Flag... flags) {
		Locality locality = Locality.forCurrentConsistentHash(this.cache);
		try (Stream> keys = this.cache.getAdvancedCache().withFlags(flags).keySet().stream()) {
			return keys.filter(SessionMetaDataKeyFilter.INSTANCE.and(key -> locality.isLocal(key))).map(key -> key.getId()).collect(Collectors.toSet());
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy