You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* adds empty async controller to be used later
* basic webflux implementation
* remove logging from json encoder
* add lightweight benchmarking script to help with optimizing async setup
* benchmarking script tweak
* update readme
* adds geometry data to Address to demonstrate postgis integration. also adds to testutils.
* update gradle
* explicitly set default profile
* better table enumeration for resetting persistence in tests
* update readme
Copy file name to clipboardExpand all lines: README.md
+19-6Lines changed: 19 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -81,20 +81,33 @@ This means that whenever you are working with variables coming Spring, you gener
81
81
One particular place to watch out for this is when using Spring's `@RequestParam` and `@PathVariable` annotations in controllers.
82
82
83
83
## Spring's ThreadLocal Context
84
-
Much of Spring's async programming model relies on ThreadLocal context. This used to be a common pattern in Java, but not one that is used in Scala.
84
+
Much of Spring's async programming model relies on ThreadLocal context, particularly when using WebMVC. This used to be a common pattern in Java, but not one that is used in Scala.
85
85
This becomes particularly annoying when interfacing between things like controller entry points and services and utilities that are built
86
86
around IO/Future/ZIO etc. monads. Effectively, trying to access something like Spring Security's SecurityContext from these methods
87
-
will not work. The best solution I have found is to pass the SecurityContext and any other ThreadLocal context as an argument to
87
+
will not work. Without going into too much detail WebFlux has the same basic problem, even though its not technically using ThreadLocal context.
88
+
89
+
The best solution I have found is to pass the SecurityContext and any other ThreadLocal / pseudo global context data as an argument to
88
90
these methods. This is not ideal, but it is the best solution I have found so far.
89
91
90
92
## Async Programming
91
93
Spring has it's own mechanisms for async programming, and it takes some work to adapt it to be compatible with IO monads.
92
-
Even after adapting these mechanisms we are left with having to manage an additional threadpool to accommodate Spring.
93
-
The other challenge here is adapting the handling of uncaught exceptions so that Spring's conventional mechanisms will
94
+
Even after adapting these mechanisms we are left with having to manage an additional threadpool(s) to accommodate Spring.
95
+
Another challenge here is adapting the handling of uncaught exceptions so that Spring's conventional mechanisms will
94
96
continue to function.
95
97
96
-
I've not gotten around to adding this to the example yet, but it is doable, and once it's done you can pretty much forget
97
-
about it.
98
+
### Async Controllers
99
+
The original version of this project used WebMVC which is built on top of Apache Tomcat and has its own async programming model.
100
+
I've since switched to using WebFlux which is built on top of Netty and is generally considered to be more performant, particularly
101
+
when it comes to servicing large numbers of requests concurrently. I would not be surprised if this changes in the future
102
+
thanks to the work being done on Project Loom. For those interested in exploring this further, check out the [webmvc tag](https://github.com/halfhp/ScalaSpringExperiment/releases/tag/webmvc)
103
+
of this repository.
104
+
105
+
### Async Database Drivers
106
+
This project uses Doobie, which is built on top of JDBC which is synchronous. There is another library, Skunk, which is written
107
+
by the same author and offers similar functionality. It's fully asynchronous but also locks you into using Postgres.
108
+
109
+
Another option would be to use one Spring's database facilities that supports R2DBC, which is also async. I've not tried this approach
110
+
yet but imagine it could be wrapped with cats-effect IO similarly to what was done with [Mono] in the controller layer.
0 commit comments