Hi Sven, I just found time to give this a try with Wicket 9.0.0-M5. There seem to be issues with serialization now.
My new config: protected IPageStore newCachingStore(IPageStore pageStore) { > return new CachingPageStore(pageStore, new InMemoryPageStore(getName(), > MAX_PAGES_CACHED_PER_SESSION)); > } > protected IPageStore newPersistentStore() { > final RedissonRedisCache redisCache = new > RedissonRedisCache(redissonClient); > final RedisDataStore redisDataStore = new RedisDataStore(getName(), > redisCache, new RedisSettings()); > return new SessionQuotaManagingDataStore(redisDataStore, > DATA_STORE_MAX_BYTES_PER_SESSION); > } This exception is logged after requests: org.springframework.data.redis.serializer.SerializationException: Cannot > serialize; nested exception is > org.springframework.core.serializer.support.SerializationFailedException: > Failed to serialize object using DefaultSerializer; nested exception is > java.io.NotSerializableException: > org.wicketstuff.datastores.common.SessionQuotaManagingDataStore$DelegatedPage > at > org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:96) > at > org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:185) > at > org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:147) > at > org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:147) > at > org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.saveDelta(RedisIndexedSessionRepository.java:795) > at > org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.save(RedisIndexedSessionRepository.java:783) > at > org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.access$000(RedisIndexedSessionRepository.java:670) > at > org.springframework.session.data.redis.RedisIndexedSessionRepository.save(RedisIndexedSessionRepository.java:398) > at > org.springframework.session.data.redis.RedisIndexedSessionRepository.save(RedisIndexedSessionRepository.java:249) > at > com.myproject.session.InstrumentedFindByIndexNameSessionRepository.save(InstrumentedFindByIndexNameSessionRepository.java:29) > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native > Method) > at > java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.base/java.lang.reflect.Method.invoke(Method.java:566) > at > org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) > at > org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) > at > org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) > at > org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88) > at > io.micrometer.core.aop.TimedAspect.processWithTimer(TimedAspect.java:105) > at io.micrometer.core.aop.TimedAspect.timedMethod(TimedAspect.java:94) > at jdk.internal.reflect.GeneratedMethodAccessor146.invoke(Unknown Source) > at > java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.base/java.lang.reflect.Method.invoke(Method.java:566) > at > org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) > at > org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) > at > org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) > at > org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) > at > org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) > at > org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) > at > org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) > at com.sun.proxy.$Proxy296.save(Unknown Source) > at > org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:225) > at > org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:192) > at > org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:144) > at > org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) > at > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) > at > org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) > at > org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:666) > at > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) > at > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) > at > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) > at > org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) > at > org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) > at > org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) > at > org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) > at > org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594) > at > org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) > at > java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) > at > java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) > at > org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) > at java.base/java.lang.Thread.run(Thread.java:834) > Caused by: > org.springframework.core.serializer.support.SerializationFailedException: > Failed to serialize object using DefaultSerializer; nested exception is > java.io.NotSerializableException: > org.wicketstuff.datastores.common.SessionQuotaManagingDataStore$DelegatedPage > at > org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:68) > at > org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35) > at > org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:94) > ... 52 common frames omitted > Caused by: java.io.NotSerializableException: > org.wicketstuff.datastores.common.SessionQuotaManagingDataStore$DelegatedPage Why does Wicket 9 try to serialize the SessionQuotaManagingDataStore in the session? Is this intended and does DelegatePage simply need to implement Serializable or shouldn't this be serialized at all? In Wicket 8, the corresponding PageData wasn't serializable either so my guess would be that this behavior is not intended. I'm using the following config for Wicket 8 and there are no such issues: protected IPageStore newPageStore(IDataStore dataStore) { > final ISerializer pageSerializer = getFrameworkSettings().getSerializer(); > return new PerSessionPageStore(pageSerializer, dataStore, > MAX_PAGES_CACHED_PER_SESSION); > } > protected IDataStore newDataStore() { > final RedissonRedisCache redisCache = new > RedissonRedisCache(redissonClient.get()); > final RedisDataStore redisDataStore = new RedisDataStore(redisCache, new > RedisSettings()); > return new SessionQuotaManagingDataStore(redisDataStore, > DATA_STORE_MAX_BYTES_PER_SESSION); > } Best regards, Thomas On Sat, Mar 28, 2020 at 10:23 AM Thomas Heigl <tho...@umschalt.com> wrote: > Thanks Sven! > > That looks much better. I'll give it a try as soon as I can. > > Best regards, > > Thomas > > On Fri, Mar 27, 2020 at 2:23 PM Sven Meier <s...@meiers.net> wrote: > >> Hi Thomas, >> >> your question comes at the right time. >> >> I was able to improve the implementation with a new CachingPageStore: >> >> >> https://github.com/apache/wicket/blob/8df3528dc44a08b7d375c20e764a3664cd6a5f30/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java#L145 >> >> You can now use InMemoryPageStore as a cache too. >> >> Have fun >> Sven >> >> >> On 27.03.20 09:34, Sven Meier wrote: >> > Hi Thomas, >> > >> > I thought I covered that usecase, but I will have to take a look. >> > >> > Thanks for testing Wicket 9 >> > Sven >> > >> > On 25.03.20 20:10, Thomas Heigl wrote: >> >> Maybe the same approach could be used as for InSessionPageStore that >> >> can be >> >> used as cache and a store: >> >> >> >> >> https://github.com/apache/wicket/commit/894799e01227781be76886b2d1cdb2a424c812e0 >> >> >> >> >> >> On Wed, Mar 25, 2020 at 6:35 PM Thomas Heigl <tho...@umschalt.com> >> >> wrote: >> >> >> >>> Hi all, >> >>> >> >>> I just merged our master in our Wicket 9 branch and I ran into an >> >>> issue: >> >>> >> >>> Our current configuration with Wicket 8 looks like this: >> >>> >> >>> PageStore = PerSessionPageStore >> >>> DataStore = RedisDataStore >> >>> >> >>> So the page store keeps the last couple of pages of a session in >> memory >> >>> and Redis is used as a persistent store. >> >>> >> >>> I tried to recreate this behavior with Wicket 9: >> >>> >> >>> SessionStore = InMemoryPageStore >> >>> PersistentStore = RedisDataStore >> >>> >> >>> This looks correct, but it *does not work* because InMemoryPage store >> >>> implements AbstractPersistentPageStore and does *not* delegate to the >> >>> next store in the chain. >> >>> >> >>> So we basically lost the option to use a memory page store in front >> >>> of a >> >>> persistent store. >> >>> >> >>> We need this functionality because we are using Spring Session and >> >>> cannot >> >>> use the session as a page store. >> >>> >> >>> Would it be possible to add an InMemory store that delegates to the >> >>> next >> >>> store in the chain? Or do I have to implement it myself? >> >>> >> >>> Best regards, >> >>> >> >>> Thomas >> >>> >> > >> > --------------------------------------------------------------------- >> > To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org >> > For additional commands, e-mail: users-h...@wicket.apache.org >> > >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org >> For additional commands, e-mail: users-h...@wicket.apache.org >> >>