Skip to content

Commit

Permalink
WebSession creation does not block
Browse files Browse the repository at this point in the history
Closes gh-24027
  • Loading branch information
rstoyanchev committed Nov 26, 2019
1 parent ddb38ee commit 70a3dbf
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 11 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -29,6 +29,7 @@
import java.util.concurrent.locks.ReentrantLock;

import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import org.springframework.util.Assert;
import org.springframework.util.IdGenerator;
Expand Down Expand Up @@ -111,9 +112,14 @@ public Map<String, WebSession> getSessions() {

@Override
public Mono<WebSession> createWebSession() {

// Opportunity to clean expired sessions
Instant now = this.clock.instant();
this.expiredSessionChecker.checkIfNecessary(now);
return Mono.fromSupplier(() -> new InMemoryWebSession(now));

return Mono.fromSupplier(() -> new InMemoryWebSession(now))
.subscribeOn(Schedulers.boundedElastic())
.cast(WebSession.class);
}

@Override
Expand Down
Expand Up @@ -22,7 +22,10 @@
import java.util.Map;
import java.util.stream.IntStream;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import org.springframework.beans.DirectFieldAccessor;
import org.springframework.web.server.WebSession;
Expand Down Expand Up @@ -56,6 +59,14 @@ public void startsSessionImplicitly() {
assertThat(session.isStarted()).isTrue();
}

@Disabled // TODO: remove if/when Blockhound is enabled
@Test // gh-24027
public void createSessionDoesNotBlock() {
Mono.defer(() -> this.store.createWebSession())
.subscribeOn(Schedulers.parallel())
.block();
}

@Test
public void retrieveExpiredSession() {
WebSession session = this.store.createWebSession().block();
Expand Down
Expand Up @@ -64,6 +64,9 @@
*/
public class ModelInitializerTests {

private static final Duration TIMEOUT = Duration.ofMillis(5000);


private ModelInitializer modelInitializer;

private final ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path"));
Expand Down Expand Up @@ -93,7 +96,7 @@ public void initBinderMethod() {

Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);

WebExchangeDataBinder binder = context.createDataBinder(this.exchange, "name");
assertThat(binder.getValidators()).isEqualTo(Collections.singletonList(validator));
Expand All @@ -107,7 +110,7 @@ public void modelAttributeMethods() {

Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);

Map<String, Object> model = context.getModel().asMap();
assertThat(model.size()).isEqualTo(5);
Expand All @@ -116,7 +119,7 @@ public void modelAttributeMethods() {
assertThat(((TestBean) value).getName()).isEqualTo("Bean");

value = model.get("monoBean");
assertThat(((Mono<TestBean>) value).block(Duration.ofMillis(5000)).getName()).isEqualTo("Mono Bean");
assertThat(((Mono<TestBean>) value).block(TIMEOUT).getName()).isEqualTo("Mono Bean");

value = model.get("singleBean");
assertThat(((Single<TestBean>) value).toBlocking().value().getName()).isEqualTo("Single Bean");
Expand All @@ -135,7 +138,7 @@ public void saveModelAttributeToSession() {

Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);

WebSession session = this.exchange.getSession().block(Duration.ZERO);
assertThat(session).isNotNull();
Expand All @@ -148,7 +151,7 @@ public void saveModelAttributeToSession() {

@Test
public void retrieveModelAttributeFromSession() {
WebSession session = this.exchange.getSession().block(Duration.ZERO);
WebSession session = this.exchange.getSession().block(TIMEOUT);
assertThat(session).isNotNull();

TestBean testBean = new TestBean("Session Bean");
Expand All @@ -159,7 +162,7 @@ public void retrieveModelAttributeFromSession() {

Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);

context.saveModel();
assertThat(session.getAttributes().size()).isEqualTo(1);
Expand All @@ -174,13 +177,13 @@ public void requiredSessionAttributeMissing() {
Method method = ResolvableMethod.on(TestController.class).annotPresent(PostMapping.class).resolveMethod();
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
assertThatIllegalArgumentException().isThrownBy(() ->
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000)))
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT))
.withMessage("Required attribute 'missing-bean' is missing.");
}

@Test
public void clearModelAttributeFromSession() {
WebSession session = this.exchange.getSession().block(Duration.ZERO);
WebSession session = this.exchange.getSession().block(TIMEOUT);
assertThat(session).isNotNull();

TestBean testBean = new TestBean("Session Bean");
Expand All @@ -191,7 +194,7 @@ public void clearModelAttributeFromSession() {

Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);

context.getSessionStatus().setComplete();
context.saveModel();
Expand Down

0 comments on commit 70a3dbf

Please sign in to comment.