@Override public int getTotalSize() { return this.getCacheSize(); }
@Override public void remove(K key) { Entry<V> entry = this.entries.remove(key); if (entry != null) { this.factory.destroyInstance(entry.getValue()); } }
@Override public void release(V bean) { K id = bean.getId(); Entry<V> entry = this.entries.get(id); if ((entry != null) && entry.done()) { if (this.timeout != null) { long value = this.timeout.getValue(); if (value > 0) { TimeUnit unit = this.timeout.getTimeUnit(); RemoveTask task = new RemoveTask(id); // Make sure the expiration future map insertion happens before map removal (during task execution). synchronized (task) { this.expirationFutures.put(id, this.executor.schedule(task, value, unit)); } } else if (value == 0) { // The EJB specification allows a 0 timeout, which means the bean is immediately eligible for removal. // However, removing it directly is faster than scheduling it for immediate removal. remove(id); } } } }
@Override public CapabilityServiceConfigurator getServiceConfigurator(ServiceName name, StatefulComponentDescription description, ComponentConfiguration configuration) { return new SimpleCacheFactoryServiceConfigurator<>(name, description, new ServiceSupplierDependency<>(this.getExpirationSchedulerServiceName(description.getDeploymentUnitServiceName()))); }
@Override public Cache<K, V> createCache(IdentifierFactory<K> identifierFactory, StatefulObjectFactory<V> factory, PassivationListener<V> passivationListener) { return new SimpleCache<>(factory, identifierFactory, this.timeout, this.environment.get(), this.executor.get()); } }
@Override public Collection<CapabilityServiceConfigurator> getDeploymentServiceConfigurators(DeploymentUnit unit) { ServiceConfigurator configurator = new RemoveOnCancelScheduledExecutorServiceConfigurator(this.getExpirationSchedulerServiceName(unit.getServiceName()), THREAD_FACTORY); return Collections.singleton(new ServiceConfiguratorAdapter(configurator)); }
@Override public V create() { if (CURRENT_GROUP.get() != null) { // An SFSB that uses a distributable cache cannot contain an SFSB that uses a simple cache throw EjbLogger.ROOT_LOGGER.incompatibleCaches(); } V bean = this.factory.createInstance(); this.entries.put(bean.getId(), new Entry<>(bean)); return bean; }
@Override public ServiceBuilder<?> build(ServiceTarget target) { ServiceName name = this.getServiceName(); ServiceBuilder<?> builder = target.addService(name); Consumer<CacheFactoryBuilder<K, V>> cacheFactoryBuilder = builder.provides(name); Service service = Service.newInstance(cacheFactoryBuilder, this); return builder.setInstance(service).setInitialMode(ServiceController.Mode.ON_DEMAND); }
@Override public ServiceBuilder<?> build(ServiceTarget target) { ServiceName name = this.getServiceName(); ServiceBuilder<?> builder = target.addService(name); Consumer<CacheFactory<K, V>> factory = new CompositeDependency(this.environment, this.executor).register(builder).provides(name); Service service = Service.newInstance(factory, this); return builder.setInstance(service); }
@Override protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException { final String name = PathAddress.pathAddress(operation.get(ModelDescriptionConstants.ADDRESS)).getLastElement().getValue(); ModelNode passivationStoreModel = CacheFactoryResourceDefinition.PASSIVATION_STORE.resolveModelAttribute(context,model); String passivationStore = passivationStoreModel.isDefined() ? passivationStoreModel.asString() : null; final Collection<String> unwrappedAliasValues = CacheFactoryResourceDefinition.ALIASES.unwrap(context,model); final Set<String> aliases = unwrappedAliasValues != null ? new HashSet<>(unwrappedAliasValues) : Collections.<String>emptySet(); ServiceTarget target = context.getServiceTarget(); ServiceConfigurator configurator = (passivationStore != null) ? new IdentityServiceConfigurator<>(new CacheFactoryBuilderServiceNameProvider(name).getServiceName(), new DistributableCacheFactoryBuilderServiceNameProvider(passivationStore).getServiceName()) : new SimpleCacheFactoryBuilderServiceConfigurator<>(name); ServiceBuilder<?> builder = configurator.build(target); for (String alias: aliases) { new IdentityServiceConfigurator<>(new CacheFactoryBuilderServiceNameProvider(alias).getServiceName(), configurator.getServiceName()).build(target).install(); } builder.install(); } }
@Override public void stop() { for (Future<?> future: this.expirationFutures.values()) { future.cancel(true); } for (Future<?> future: this.expirationFutures.values()) { if (!future.isCancelled() && !future.isDone()) { try { future.get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } catch (ExecutionException e) { // Ignore } } } for(Map.Entry<K, Entry<V>> entry : entries.entrySet()) { this.factory.destroyInstance(entry.getValue().getValue()); } this.expirationFutures.clear(); this.entries.clear(); }