Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WFLY-5502 & WFLY-5503 Distributed web session behavioral fixes for local/invalidation cache modes #8265

Merged
merged 2 commits into from Oct 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -115,7 +115,7 @@ public InfinispanSessionManager(SessionFactory<V, L> factory, InfinispanSessionM
// If cache is clustered or configured with a write-through cache store
// then we need to trigger any HttpSessionActivationListeners per request
// See SRV.7.7.2 Distributed Environments
this.persistent = config.clustering().cacheMode().isClustered() || (config.persistence().usingStores() && !config.persistence().passivation());
this.persistent = config.clustering().cacheMode().needsStateTransfer() || (config.persistence().usingStores() && !config.persistence().passivation());
}

@Override
Expand Down
Expand Up @@ -159,15 +159,16 @@ private <L> SessionFactory<?, L> getSessionFactory(SessionContext context, Local
Cache<Key<String>, ?> cache = this.config.getCache();
Configuration cacheConfig = cache.getCacheConfiguration();
boolean lockOnRead = cacheConfig.transaction().transactionMode().isTransactional() && (cacheConfig.transaction().lockingMode() == LockingMode.PESSIMISTIC) && cacheConfig.locking().isolationLevel() == IsolationLevel.REPEATABLE_READ;
boolean requireMarshallable = cacheConfig.clustering().cacheMode().needsStateTransfer() || cacheConfig.persistence().usingStores();

switch (config.getAttributePersistenceStrategy()) {
case FINE: {
Marshaller<Object, MarshalledValue<Object, MarshallingContext>, MarshallingContext> marshaller = new MarshalledValueMarshaller<>(factory, marshallingContext);
return new FineSessionFactory<>(cache, context, marshaller, localContextFactory, lockOnRead);
return new FineSessionFactory<>(cache, context, marshaller, localContextFactory, lockOnRead, requireMarshallable);
}
case COARSE: {
Marshaller<Map<String, Object>, MarshalledValue<Map<String, Object>, MarshallingContext>, MarshallingContext> marshaller = new MarshalledValueMarshaller<>(factory, marshallingContext);
return new CoarseSessionFactory<>(cache, context, marshaller, localContextFactory, lockOnRead);
return new CoarseSessionFactory<>(cache, context, marshaller, localContextFactory, lockOnRead, requireMarshallable);
}
default: {
// Impossible
Expand Down
Expand Up @@ -37,12 +37,14 @@ public class CoarseSessionAttributes extends CoarseImmutableSessionAttributes im
private final Map<String, Object> attributes;
private final Mutator mutator;
private final MarshallingContext context;
private final boolean requireMarshallable;

public CoarseSessionAttributes(Map<String, Object> attributes, Mutator mutator, MarshallingContext context) {
public CoarseSessionAttributes(Map<String, Object> attributes, Mutator mutator, MarshallingContext context, boolean requireMarshallable) {
super(attributes);
this.attributes = attributes;
this.mutator = mutator;
this.context = context;
this.requireMarshallable = requireMarshallable;
}

@Override
Expand All @@ -57,7 +59,7 @@ public Object setAttribute(String name, Object value) {
if (value == null) {
return this.removeAttribute(name);
}
if (!this.context.isMarshallable(value)) {
if (this.requireMarshallable && !this.context.isMarshallable(value)) {
throw new IllegalArgumentException(new NotSerializableException(value.getClass().getName()));
}
Object old = this.attributes.put(name, value);
Expand Down
Expand Up @@ -72,16 +72,18 @@ public class CoarseSessionFactory<L> implements SessionFactory<CoarseSessionEntr
private final Cache<SessionAttributesKey, MarshalledValue<Map<String, Object>, MarshallingContext>> attributesCache;
private final Marshaller<Map<String, Object>, MarshalledValue<Map<String, Object>, MarshallingContext>, MarshallingContext> marshaller;
private final LocalContextFactory<L> localContextFactory;
private final boolean requireMarshallable;

@SuppressWarnings("unchecked")
public CoarseSessionFactory(Cache<? extends Key<String>, ?> cache, SessionContext context, Marshaller<Map<String, Object>, MarshalledValue<Map<String, Object>, MarshallingContext>, MarshallingContext> marshaller, LocalContextFactory<L> localContextFactory, boolean lockOnRead) {
public CoarseSessionFactory(Cache<? extends Key<String>, ?> cache, SessionContext context, Marshaller<Map<String, Object>, MarshalledValue<Map<String, Object>, MarshallingContext>, MarshallingContext> marshaller, LocalContextFactory<L> localContextFactory, boolean lockOnRead, boolean requireMarshallable) {
this.creationMetaDataCache = (Cache<SessionCreationMetaDataKey, SessionCreationMetaDataEntry<L>>) cache;
this.findCreationMetaDataCache = lockOnRead ? this.creationMetaDataCache.getAdvancedCache().withFlags(Flag.FORCE_WRITE_LOCK) : this.creationMetaDataCache;
this.accessMetaDataCache = (Cache<SessionAccessMetaDataKey, SessionAccessMetaData>) cache;
this.attributesCache = (Cache<SessionAttributesKey, MarshalledValue<Map<String, Object>, MarshallingContext>>) cache;
this.context = context;
this.marshaller = marshaller;
this.localContextFactory = localContextFactory;
this.requireMarshallable = requireMarshallable;
}

@Override
Expand All @@ -93,7 +95,7 @@ public Session<L> createSession(String id, CoarseSessionEntry<L> entry) {
SessionCreationMetaData creationMetaData = new MutableSessionCreationMetaData(creationMetaDataEntry.getValue(), creationMetaDataEntry.getMutator());
SessionAccessMetaData accessMetaData = new MutableSessionAccessMetaData(accessMetaDataEntry.getValue(), accessMetaDataEntry.getMutator());
SessionMetaData metaData = new SimpleSessionMetaData(creationMetaData, accessMetaData);
SessionAttributes attributes = new CoarseSessionAttributes(attributesEntry.getValue(), attributesEntry.getMutator(), this.marshaller.getContext());
SessionAttributes attributes = new CoarseSessionAttributes(attributesEntry.getValue(), attributesEntry.getMutator(), this.marshaller.getContext(), this.requireMarshallable);

return new InfinispanSession<>(id, metaData, attributes, entry.getLocalContext(), this.localContextFactory, this.context, this);
}
Expand Down
Expand Up @@ -37,11 +37,13 @@
public class FineSessionAttributes<V> extends FineImmutableSessionAttributes<V> implements SessionAttributes {
private final Cache<SessionAttributeKey, V> cache;
private final Marshaller<Object, V, MarshallingContext> marshaller;
private final boolean requireMarshallable;

public FineSessionAttributes(String id, Cache<SessionAttributeKey, V> attributeCache, Marshaller<Object, V, MarshallingContext> marshaller) {
public FineSessionAttributes(String id, Cache<SessionAttributeKey, V> attributeCache, Marshaller<Object, V, MarshallingContext> marshaller, boolean requireMarshallable) {
super(id, attributeCache, marshaller);
this.cache = attributeCache;
this.marshaller = marshaller;
this.requireMarshallable = requireMarshallable;
}

@Override
Expand All @@ -55,7 +57,7 @@ public Object setAttribute(String name, Object attribute) {
if (attribute == null) {
return this.removeAttribute(name);
}
if (!this.marshaller.getContext().isMarshallable(attribute)) {
if (this.requireMarshallable && !this.marshaller.getContext().isMarshallable(attribute)) {
throw new IllegalArgumentException(new NotSerializableException(attribute.getClass().getName()));
}
SessionAttributeKey key = this.createKey(name);
Expand Down
Expand Up @@ -75,16 +75,18 @@ public class FineSessionFactory<L> implements SessionFactory<FineSessionEntry<L>
private final Marshaller<Object, MarshalledValue<Object, MarshallingContext>, MarshallingContext> marshaller;
private final LocalContextFactory<L> localContextFactory;
private final Predicate<Map.Entry<SessionAttributeKey, MarshalledValue<Object, MarshallingContext>>> invalidAttribute;
private final boolean requireMarshallable;

@SuppressWarnings("unchecked")
public FineSessionFactory(Cache<? extends Key<String>, ?> cache, SessionContext context, Marshaller<Object, MarshalledValue<Object, MarshallingContext>, MarshallingContext> marshaller, LocalContextFactory<L> localContextFactory, boolean lockOnRead) {
public FineSessionFactory(Cache<? extends Key<String>, ?> cache, SessionContext context, Marshaller<Object, MarshalledValue<Object, MarshallingContext>, MarshallingContext> marshaller, LocalContextFactory<L> localContextFactory, boolean lockOnRead, boolean requireMarshallable) {
this.creationMetaDataCache = (Cache<SessionCreationMetaDataKey, SessionCreationMetaDataEntry<L>>) cache;
this.findCreationMetaDataCache = lockOnRead ? this.creationMetaDataCache.getAdvancedCache().withFlags(Flag.FORCE_WRITE_LOCK) : this.creationMetaDataCache;
this.accessMetaDataCache = (Cache<SessionAccessMetaDataKey, SessionAccessMetaData>) cache;
this.attributeCache = (Cache<SessionAttributeKey, MarshalledValue<Object, MarshallingContext>>) cache;
this.context = context;
this.marshaller = marshaller;
this.localContextFactory = localContextFactory;
this.requireMarshallable = requireMarshallable;
this.invalidAttribute = entry -> {
try {
this.marshaller.read(entry.getValue());
Expand All @@ -105,7 +107,7 @@ public Session<L> createSession(String id, FineSessionEntry<L> entry) {
SessionAccessMetaData accessMetaData = new MutableSessionAccessMetaData(accessMetaDataEntry.getValue(), accessMetaDataEntry.getMutator());
SessionMetaData metaData = new SimpleSessionMetaData(creationMetaData, accessMetaData);

SessionAttributes attributes = new FineSessionAttributes<>(id, this.attributeCache, this.marshaller);
SessionAttributes attributes = new FineSessionAttributes<>(id, this.attributeCache, this.marshaller, this.requireMarshallable);
return new InfinispanSession<>(id, metaData, attributes, entry.getLocalContext(), this.localContextFactory, this.context, this);
}

Expand Down