Skip to content

Commit 1698b32

Browse files
committed
Further changes and improvements.
1 parent ee76599 commit 1698b32

File tree

18 files changed

+824
-80
lines changed

18 files changed

+824
-80
lines changed
Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
11
Gatling plugin for Maven - Java demo project
22
============================================
33

4-
A simple showcase of a Maven project using the Gatling plugin for Maven. Refer to the plugin documentation
5-
[on the Gatling website](https://gatling.io/docs/current/extensions/maven_plugin/) for usage.
4+
To run the gatling use followning
65

7-
This project is written in Java, others are available for [Kotlin](https://github.com/gatling/gatling-maven-plugin-demo-kotlin)
8-
and [Scala](https://github.com/gatling/gatling-maven-plugin-demo-scala).
6+
```bash
7+
./mvnw gatling:test
98

10-
It includes:
11-
12-
* [Maven Wrapper](https://maven.apache.org/wrapper/), so that you can immediately run Maven with `./mvnw` without having
13-
to install it on your computer
14-
* minimal `pom.xml`
15-
* latest version of `io.gatling:gatling-maven-plugin` applied
16-
* sample [Simulation](https://gatling.io/docs/gatling/reference/current/general/concepts/#simulation) class,
17-
demonstrating sufficient Gatling functionality
18-
* proper source file layout
9+
```
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.2">
3+
<hashTree>
4+
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
5+
<boolProp name="TestPlan.functional_mode">false</boolProp>
6+
<boolProp name="TestPlan.tearDown_on_shutdown">false</boolProp>
7+
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
8+
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
9+
<collectionProp name="Arguments.arguments"/>
10+
</elementProp>
11+
</TestPlan>
12+
<hashTree>
13+
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Tset-Normal" enabled="false">
14+
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
15+
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
16+
<stringProp name="LoopController.loops">1</stringProp>
17+
<boolProp name="LoopController.continue_forever">false</boolProp>
18+
</elementProp>
19+
<stringProp name="ThreadGroup.num_threads">4</stringProp>
20+
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
21+
<boolProp name="ThreadGroup.delayedStart">false</boolProp>
22+
<boolProp name="ThreadGroup.scheduler">false</boolProp>
23+
<stringProp name="ThreadGroup.duration"></stringProp>
24+
<stringProp name="ThreadGroup.delay"></stringProp>
25+
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
26+
</ThreadGroup>
27+
<hashTree>
28+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Test-Normal" enabled="true">
29+
<boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
30+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
31+
<collectionProp name="Arguments.arguments"/>
32+
</elementProp>
33+
<stringProp name="HTTPSampler.domain">localhost</stringProp>
34+
<stringProp name="HTTPSampler.port">8080</stringProp>
35+
<stringProp name="HTTPSampler.protocol">http</stringProp>
36+
<stringProp name="HTTPSampler.path">test</stringProp>
37+
<stringProp name="HTTPSampler.method">GET</stringProp>
38+
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
39+
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
40+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
41+
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
42+
<boolProp name="HTTPSampler.BROWSER_COMPATIBLE_MULTIPART">false</boolProp>
43+
<boolProp name="HTTPSampler.image_parser">false</boolProp>
44+
<boolProp name="HTTPSampler.concurrentDwn">false</boolProp>
45+
<stringProp name="HTTPSampler.concurrentPool">6</stringProp>
46+
<boolProp name="HTTPSampler.md5">false</boolProp>
47+
<intProp name="HTTPSampler.ipSourceType">0</intProp>
48+
</HTTPSamplerProxy>
49+
<hashTree/>
50+
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
51+
<boolProp name="ResultCollector.error_logging">false</boolProp>
52+
<objProp>
53+
<name>saveConfig</name>
54+
<value class="SampleSaveConfiguration">
55+
<time>true</time>
56+
<latency>true</latency>
57+
<timestamp>true</timestamp>
58+
<success>true</success>
59+
<label>true</label>
60+
<code>true</code>
61+
<message>true</message>
62+
<threadName>true</threadName>
63+
<dataType>true</dataType>
64+
<encoding>false</encoding>
65+
<assertions>true</assertions>
66+
<subresults>true</subresults>
67+
<responseData>false</responseData>
68+
<samplerData>false</samplerData>
69+
<xml>false</xml>
70+
<fieldNames>true</fieldNames>
71+
<responseHeaders>false</responseHeaders>
72+
<requestHeaders>false</requestHeaders>
73+
<responseDataOnError>false</responseDataOnError>
74+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
75+
<assertionsResultsToSave>0</assertionsResultsToSave>
76+
<bytes>true</bytes>
77+
<sentBytes>true</sentBytes>
78+
<url>true</url>
79+
<threadCounts>true</threadCounts>
80+
<idleTime>true</idleTime>
81+
<connectTime>true</connectTime>
82+
</value>
83+
</objProp>
84+
<stringProp name="filename"></stringProp>
85+
</ResultCollector>
86+
<hashTree/>
87+
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
88+
<boolProp name="ResultCollector.error_logging">false</boolProp>
89+
<objProp>
90+
<name>saveConfig</name>
91+
<value class="SampleSaveConfiguration">
92+
<time>true</time>
93+
<latency>true</latency>
94+
<timestamp>true</timestamp>
95+
<success>true</success>
96+
<label>true</label>
97+
<code>true</code>
98+
<message>true</message>
99+
<threadName>true</threadName>
100+
<dataType>true</dataType>
101+
<encoding>false</encoding>
102+
<assertions>true</assertions>
103+
<subresults>true</subresults>
104+
<responseData>false</responseData>
105+
<samplerData>false</samplerData>
106+
<xml>false</xml>
107+
<fieldNames>true</fieldNames>
108+
<responseHeaders>false</responseHeaders>
109+
<requestHeaders>false</requestHeaders>
110+
<responseDataOnError>false</responseDataOnError>
111+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
112+
<assertionsResultsToSave>0</assertionsResultsToSave>
113+
<bytes>true</bytes>
114+
<sentBytes>true</sentBytes>
115+
<url>true</url>
116+
<threadCounts>true</threadCounts>
117+
<idleTime>true</idleTime>
118+
<connectTime>true</connectTime>
119+
</value>
120+
</objProp>
121+
<stringProp name="filename"></stringProp>
122+
</ResultCollector>
123+
<hashTree/>
124+
</hashTree>
125+
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Test-Async" enabled="true">
126+
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
127+
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
128+
<stringProp name="LoopController.loops">1</stringProp>
129+
<boolProp name="LoopController.continue_forever">false</boolProp>
130+
</elementProp>
131+
<stringProp name="ThreadGroup.num_threads">7</stringProp>
132+
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
133+
<boolProp name="ThreadGroup.delayedStart">false</boolProp>
134+
<boolProp name="ThreadGroup.scheduler">false</boolProp>
135+
<stringProp name="ThreadGroup.duration"></stringProp>
136+
<stringProp name="ThreadGroup.delay"></stringProp>
137+
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
138+
</ThreadGroup>
139+
<hashTree>
140+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Test-Async" enabled="true">
141+
<boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
142+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
143+
<collectionProp name="Arguments.arguments"/>
144+
</elementProp>
145+
<stringProp name="HTTPSampler.domain">localhost</stringProp>
146+
<stringProp name="HTTPSampler.port">8080</stringProp>
147+
<stringProp name="HTTPSampler.protocol">http</stringProp>
148+
<stringProp name="HTTPSampler.path">test/async</stringProp>
149+
<stringProp name="HTTPSampler.method">GET</stringProp>
150+
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
151+
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
152+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
153+
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
154+
<boolProp name="HTTPSampler.BROWSER_COMPATIBLE_MULTIPART">false</boolProp>
155+
<boolProp name="HTTPSampler.image_parser">false</boolProp>
156+
<boolProp name="HTTPSampler.concurrentDwn">false</boolProp>
157+
<stringProp name="HTTPSampler.concurrentPool">6</stringProp>
158+
<boolProp name="HTTPSampler.md5">false</boolProp>
159+
<intProp name="HTTPSampler.ipSourceType">0</intProp>
160+
</HTTPSamplerProxy>
161+
<hashTree/>
162+
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
163+
<boolProp name="ResultCollector.error_logging">false</boolProp>
164+
<objProp>
165+
<name>saveConfig</name>
166+
<value class="SampleSaveConfiguration">
167+
<time>true</time>
168+
<latency>true</latency>
169+
<timestamp>true</timestamp>
170+
<success>true</success>
171+
<label>true</label>
172+
<code>true</code>
173+
<message>true</message>
174+
<threadName>true</threadName>
175+
<dataType>true</dataType>
176+
<encoding>false</encoding>
177+
<assertions>true</assertions>
178+
<subresults>true</subresults>
179+
<responseData>false</responseData>
180+
<samplerData>false</samplerData>
181+
<xml>false</xml>
182+
<fieldNames>true</fieldNames>
183+
<responseHeaders>false</responseHeaders>
184+
<requestHeaders>false</requestHeaders>
185+
<responseDataOnError>false</responseDataOnError>
186+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
187+
<assertionsResultsToSave>0</assertionsResultsToSave>
188+
<bytes>true</bytes>
189+
<sentBytes>true</sentBytes>
190+
<url>true</url>
191+
<threadCounts>true</threadCounts>
192+
<idleTime>true</idleTime>
193+
<connectTime>true</connectTime>
194+
</value>
195+
</objProp>
196+
<stringProp name="filename"></stringProp>
197+
</ResultCollector>
198+
<hashTree/>
199+
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
200+
<boolProp name="ResultCollector.error_logging">false</boolProp>
201+
<objProp>
202+
<name>saveConfig</name>
203+
<value class="SampleSaveConfiguration">
204+
<time>true</time>
205+
<latency>true</latency>
206+
<timestamp>true</timestamp>
207+
<success>true</success>
208+
<label>true</label>
209+
<code>true</code>
210+
<message>true</message>
211+
<threadName>true</threadName>
212+
<dataType>true</dataType>
213+
<encoding>false</encoding>
214+
<assertions>true</assertions>
215+
<subresults>true</subresults>
216+
<responseData>false</responseData>
217+
<samplerData>false</samplerData>
218+
<xml>false</xml>
219+
<fieldNames>true</fieldNames>
220+
<responseHeaders>false</responseHeaders>
221+
<requestHeaders>false</requestHeaders>
222+
<responseDataOnError>false</responseDataOnError>
223+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
224+
<assertionsResultsToSave>0</assertionsResultsToSave>
225+
<bytes>true</bytes>
226+
<sentBytes>true</sentBytes>
227+
<url>true</url>
228+
<threadCounts>true</threadCounts>
229+
<idleTime>true</idleTime>
230+
<connectTime>true</connectTime>
231+
</value>
232+
</objProp>
233+
<stringProp name="filename"></stringProp>
234+
</ResultCollector>
235+
<hashTree/>
236+
</hashTree>
237+
</hashTree>
238+
</hashTree>
239+
</jmeterTestPlan>

virtual-thread/jmeter/Thread-per-task.jmx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<stringProp name="LoopController.loops">1</stringProp>
1717
<boolProp name="LoopController.continue_forever">false</boolProp>
1818
</elementProp>
19-
<stringProp name="ThreadGroup.num_threads">8</stringProp>
19+
<stringProp name="ThreadGroup.num_threads">7</stringProp>
2020
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
2121
<boolProp name="ThreadGroup.delayedStart">false</boolProp>
2222
<boolProp name="ThreadGroup.scheduler">false</boolProp>

virtual-thread/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
<module>virtual-thread-other-pattern</module>
2626
<module>old-spring-boot</module>
2727
<module>thread-local</module>
28+
<module>servlet-async</module>
29+
<module>spring-async-responsive</module>
2830
</modules>
2931

3032
</project>

virtual-thread/servlet-async/pom.xml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>com.talentica.virtual-thread</groupId>
6+
<artifactId>servlet-async</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<packaging>jar</packaging>
9+
10+
<dependencies>
11+
<!-- Servlet API -->
12+
<dependency>
13+
<groupId>javax.servlet</groupId>
14+
<artifactId>javax.servlet-api</artifactId>
15+
<version>4.0.1</version>
16+
<scope>provided</scope>
17+
</dependency>
18+
19+
<!-- Embedded Tomcat -->
20+
<dependency>
21+
<groupId>org.apache.tomcat.embed</groupId>
22+
<artifactId>tomcat-embed-core</artifactId>
23+
<version>9.0.41</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.apache.tomcat.embed</groupId>
27+
<artifactId>tomcat-embed-jasper</artifactId>
28+
<version>9.0.41</version>
29+
</dependency>
30+
</dependencies>
31+
32+
<build>
33+
<plugins>
34+
<plugin>
35+
<groupId>org.apache.maven.plugins</groupId>
36+
<artifactId>maven-compiler-plugin</artifactId>
37+
<version>3.8.1</version>
38+
<configuration>
39+
<source>1.8</source>
40+
<target>1.8</target>
41+
</configuration>
42+
</plugin>
43+
44+
<plugin>
45+
<groupId>org.apache.maven.plugins</groupId>
46+
<artifactId>maven-shade-plugin</artifactId>
47+
<version>3.2.4</version>
48+
<executions>
49+
<execution>
50+
<phase>package</phase>
51+
<goals>
52+
<goal>shade</goal>
53+
</goals>
54+
</execution>
55+
</executions>
56+
</plugin>
57+
</plugins>
58+
</build>
59+
</project>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.example;
2+
3+
import javax.servlet.AsyncContext;
4+
import javax.servlet.ServletException;
5+
import javax.servlet.ServletResponse;
6+
import javax.servlet.annotation.WebServlet;
7+
import javax.servlet.http.HttpServlet;
8+
import javax.servlet.http.HttpServletRequest;
9+
import javax.servlet.http.HttpServletResponse;
10+
import java.io.IOException;
11+
import java.io.PrintWriter;
12+
import java.util.concurrent.ExecutorService;
13+
import java.util.concurrent.Executors;
14+
15+
@WebServlet(name = "AsyncTestServlet", urlPatterns = {"/test/async"}, asyncSupported = true)
16+
public class AsyncTestServlet extends HttpServlet {
17+
private ExecutorService executorService = Executors.newFixedThreadPool(5); // Example: 5 threads
18+
19+
@Override
20+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
21+
System.out.println("Main Thread: " + Thread.currentThread().getName());
22+
usingStartAsync(req, resp);
23+
System.out.println("Response started");
24+
}
25+
26+
private void usingStartAsync(HttpServletRequest req, HttpServletResponse resp) {
27+
AsyncContext asyncContext = req.startAsync(req, resp);
28+
executorService.submit(() -> {
29+
System.out.println("Async Thread: " + Thread.currentThread().getName());
30+
try {
31+
32+
ServletResponse response = asyncContext.getResponse();
33+
response.setContentType("text/plain");
34+
PrintWriter out = response.getWriter();
35+
Thread.sleep(5000); // Simulate some processing time
36+
out.print("Hello, World!");
37+
out.flush();
38+
asyncContext.complete();
39+
} catch (InterruptedException | IOException e) {
40+
throw new RuntimeException(e);
41+
} finally {
42+
asyncContext.complete();
43+
}
44+
});
45+
46+
47+
}
48+
49+
@Override
50+
public void destroy() {
51+
executorService.shutdown();
52+
}
53+
}

0 commit comments

Comments
 (0)