Skip to content

Commit 57bf8ac

Browse files
committed
Cascade cache invalidations to dependent cached type graphs to avoid failure scenario when a chain of cached graphs as an invalidation in internal node of chain.
1 parent 2dcf7e4 commit 57bf8ac

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### Unreleased
44

55
* Remove `CacheType.EXTERNAL` as no longer in use.
6+
* Cascade cache invalidations to dependent cached type graphs to avoid failure scenario when a chain of cached graphs as an invalidation in internal node of chain.
67

78
### [v6.126](https://github.com/replicant4j/replicant/tree/v6.126) (2022-09-27) · [Full Changelog](https://github.com/spritz/spritz/compare/v6.125...v6.126)
89

server/src/main/java/org/realityforge/replicant/server/transport/ChannelMetaData.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package org.realityforge.replicant.server.transport;
22

3+
import java.util.Collections;
4+
import java.util.HashSet;
35
import java.util.Objects;
6+
import java.util.Set;
47
import javax.annotation.Nonnull;
58
import javax.annotation.Nullable;
9+
import org.jetbrains.annotations.Contract;
10+
import org.jetbrains.annotations.UnmodifiableView;
611

712
@SuppressWarnings( "WeakerAccess" )
813
public final class ChannelMetaData
@@ -62,6 +67,8 @@ public enum CacheType
6267
private final boolean _external;
6368
@Nonnull
6469
private final ChannelMetaData[] _requiredTypeChannels;
70+
@Nonnull
71+
private final Set<ChannelMetaData> _dependentChannels = new HashSet<>();
6572

6673
public ChannelMetaData( final int channelId,
6774
@Nonnull final String name,
@@ -97,6 +104,7 @@ else if ( hasFilterParameter() && null == filterParameterType )
97104
throw new IllegalArgumentException( "Specified RequiredTypeChannel " + requiredTypeChannel.getName() +
98105
" is not a type channel" );
99106
}
107+
requiredTypeChannel._dependentChannels.add( this );
100108
}
101109
}
102110

@@ -172,4 +180,12 @@ public ChannelMetaData[] getRequiredTypeChannels()
172180
{
173181
return _requiredTypeChannels;
174182
}
183+
184+
@Contract( pure = true )
185+
@Nonnull
186+
@UnmodifiableView
187+
public Set<ChannelMetaData> getDependentChannels()
188+
{
189+
return Collections.unmodifiableSet( _dependentChannels );
190+
}
175191
}

server/src/main/java/org/realityforge/replicant/server/transport/ReplicantSessionManagerImpl.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,27 @@ protected boolean deleteCacheEntry( @Nonnull final ChannelAddress address )
958958
_cacheLock.writeLock().lock();
959959
try
960960
{
961-
return null != _cache.remove( address );
961+
final ChannelMetaData metaData = getSystemMetaData().getChannelMetaData( address );
962+
final boolean cacheRemoved = null != _cache.remove( address );
963+
if ( cacheRemoved )
964+
{
965+
// If we expire the cache then any dependent type graphs must also be expired. This is
966+
// required as when a cache is on a client then we send back a "use-cache" message immediately
967+
// whereas if a message for a cached has to be loaded and sent back then we queue it on
968+
// ReplicantSession._pendingSubscriptionPackets and will be sent back. Unfortunately as we chain
969+
// up required graphs when sending cached results this may cause the later "use-cached" to arrive
970+
// before cache response and thus causing a failure on client. The "fix" is to queue the use-cache
971+
// on _pendingSubscriptionPackets but until that is implemented when we invalidate a cache we
972+
// invalidate all dependent cached type graphs to avoid this scenario.
973+
for ( final ChannelMetaData channel : metaData.getDependentChannels() )
974+
{
975+
if( channel.isTypeGraph() && channel.isCacheable() )
976+
{
977+
_cache.remove( new ChannelAddress( channel.getChannelId() ) );
978+
}
979+
}
980+
}
981+
return cacheRemoved;
962982
}
963983
finally
964984
{

0 commit comments

Comments
 (0)