This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/groovy-dev-site.git
The following commit(s) were added to refs/heads/asf-site by this push:
new 71780682 2026/07/12 04:31:49: Generated dev website from
groovy-website@aa654a4
71780682 is described below
commit 7178068299ea6f66c75ce4b3b4c756c8b35cb8a0
Author: jenkins <[email protected]>
AuthorDate: Sun Jul 12 04:31:49 2026 +0000
2026/07/12 04:31:49: Generated dev website from groovy-website@aa654a4
---
blog/feed.atom | 12 +-
blog/fizzbuzz-with-groovy-and-emojis.html | 2 +-
blog/gpars-meets-virtual-threads.html | 24 ++-
blog/groovy-async-await.html | 39 ++---
blog/groovy-list-processing-cheat-sheet.html | 2 +-
blog/groovy-pekko-gpars.html | 212 ++++++++++++++-------------
blog/index.html | 4 +-
search/search-index.json | 14 +-
8 files changed, 170 insertions(+), 139 deletions(-)
diff --git a/blog/feed.atom b/blog/feed.atom
index 32df1b1b..032f2d31 100644
--- a/blog/feed.atom
+++ b/blog/feed.atom
@@ -4,7 +4,7 @@
<link href="http://groovy.apache.org/blog"/>
<link href="http://groovy.apache.org/blog/feed.atom" rel="self"/>
<id>http://groovy.apache.org/blog</id>
- <updated>2026-07-08T20:00:00Z</updated>
+ <updated>2026-07-12T00:00:00Z</updated>
<entry>
<id>http://groovy.apache.org/blog/groovy6-formal-methods</id>
<author>
@@ -89,7 +89,7 @@
</author>
<title type="html">Async/await for Groovy&trade;</title>
<link href="http://groovy.apache.org/blog/groovy-async-await"/>
- <updated>2026-04-06T23:35:00Z</updated>
+ <updated>2026-07-12T00:00:00Z</updated>
<published>2026-03-27T16:30:00Z</published>
<summary type="html">Groovy's async/await: write concurrent code that
reads like synchronous code, with virtual thread support, generators, channels,
&amp; structured concurrency.</summary>
</entry>
@@ -362,11 +362,11 @@
<author>
<name>Paul King</name>
</author>
- <title type="html">Using Apache Pekko actors and GPars actors with
Groovy&trade;</title>
+ <title type="html">Using Apache Pekko actors and Groovy&trade; 6
actors</title>
<link href="http://groovy.apache.org/blog/groovy-pekko-gpars"/>
- <updated>2024-09-28T04:59:00Z</updated>
+ <updated>2026-07-12T00:00:00Z</updated>
<published>2023-07-17T23:24:56Z</published>
- <summary type="html">This post looks at using Apache Pekko Actors and
GPars Actors with Groovy.</summary>
+ <summary type="html">This post looks at using Apache Pekko Actors and
Groovy 6's built-in groovy.concurrent Actors.</summary>
</entry>
<entry>
<id>http://groovy.apache.org/blog/groovy-dauphine</id>
@@ -837,7 +837,7 @@
</author>
<title type="html">GPars meets Virtual Threads</title>
<link href="http://groovy.apache.org/blog/gpars-meets-virtual-threads"/>
- <updated>2023-04-14T18:23:00Z</updated>
+ <updated>2026-07-12T00:00:00Z</updated>
<published>2022-06-15T11:28:56Z</published>
<summary type="html">This post looks at using GPars with virtual
threads.</summary>
</entry>
diff --git a/blog/fizzbuzz-with-groovy-and-emojis.html
b/blog/fizzbuzz-with-groovy-and-emojis.html
index 54f24d12..fdda3cf4 100644
--- a/blog/fizzbuzz-with-groovy-and-emojis.html
+++ b/blog/fizzbuzz-with-groovy-and-emojis.html
@@ -63,7 +63,7 @@
</ul>
</div>
</div>
- </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>FizzBuzz with Groovy and Emojis</a></li><li><a
href='#_introduction' class='anchor-link'>Introduction</a></li><li><a
href='#_the_idiomatic_switch' class='anchor-link'>The idiomatic
switch</a></li><li><a href='#_the_nested_ternary' class='anchor-link'>The
nested ternary</a> [...]
+ </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>FizzBuzz with Groovy and Emojis</a></li><li><a
href='#_introduction' class='anchor-link'>Introduction</a></li><li><a
href='#_the_idiomatic_switch' class='anchor-link'>The idiomatic
switch</a></li><li><a href='#_the_nested_ternary' class='anchor-link'>The
nested ternary</a> [...]
<a href="https://github.com/paulk-asert/" target="_blank" rel="noopener
noreferrer"><img style="border-radius:50%;height:48px;width:auto"
src="img/paulk-asert.png" alt="Paul King"></a>
<div style="display:grid;align-items:center;margin:0.1ex;padding:0ex">
<div><a href="https://github.com/paulk-asert/" target="_blank" rel="noopener
noreferrer"><span>Paul King</span></a></div>
diff --git a/blog/gpars-meets-virtual-threads.html
b/blog/gpars-meets-virtual-threads.html
index 86c01e95..60add64e 100644
--- a/blog/gpars-meets-virtual-threads.html
+++ b/blog/gpars-meets-virtual-threads.html
@@ -63,7 +63,7 @@
</ul>
</div>
</div>
- </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>GPars meets Virtual Threads</a></li><li><a
href='#_parallel_collections' class='anchor-link'>Parallel
Collections</a></li><li><a href='#_agents'
class='anchor-link'>Agents</a></li><li><a href='#_actors'
class='anchor-link'>Actors</a></li><li><a href='#_dataflow' class='anc [...]
+ </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>GPars meets Virtual Threads</a></li><li><a
href='#_parallel_collections' class='anchor-link'>Parallel
Collections</a></li><li><a href='#_agents'
class='anchor-link'>Agents</a></li><li><a href='#_actors'
class='anchor-link'>Actors</a></li><li><a href='#_dataflow' class='anc [...]
<div class="sectionbody">
<div class="paragraph">
<p><span class="image right"><img src="./img/gpars_logo.png" alt="gpars"
width="150"></span>
@@ -86,6 +86,28 @@ many useful features. Let’s have a look at a few
examples.</p>
thread support as standard. Or use a recent JDK19-20 version
and enable <em>preview</em> features with your Groovy tooling.</p>
</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content">
+<div class="paragraph">
+<p><strong>Groovy 6 update:</strong> Since this post was written, Groovy 6
added a native
+concurrency and parallel-processing toolkit in the
<code>groovy.concurrent</code> package
+(GEP-18) — parallel collections, agents, actors, dataflow variables, and
+Go-style channels — all virtual-thread-first and composable with
+<a
href="https://groovy.apache.org/blog/groovy-async-await"><code>async</code>/<code>await</code></a>.
If you are on
+Groovy 6 or later, prefer those built-in features; a good starting point is the
+<a href="https://groovy.apache.org/blog/groovy-async-await">Async/await for
Groovy</a> post.
+This post remains a useful reference if you are on an earlier Groovy version or
+are maintaining an existing GPars codebase.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
</div>
</div>
<div class="sect1">
diff --git a/blog/groovy-async-await.html b/blog/groovy-async-await.html
index 38d0bede..1991911a 100644
--- a/blog/groovy-async-await.html
+++ b/blog/groovy-async-await.html
@@ -63,13 +63,13 @@
</ul>
</div>
</div>
- </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>Async/await for Groovy™</a></li><li><a href='#_introduction'
class='anchor-link'>Introduction</a></li><li><a href='#_getting_started'
class='anchor-link'>Getting started</a></li><li><a
href='#_running_tasks_in_parallel' class='anchor-link'>Running tasks in
parallel</ [...]
+ </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>Async/await for Groovy™</a></li><li><a href='#_introduction'
class='anchor-link'>Introduction</a></li><li><a href='#_getting_started'
class='anchor-link'>Getting started</a></li><li><a
href='#_running_tasks_in_parallel' class='anchor-link'>Running tasks in
parallel</ [...]
<a href="https://github.com/paulk-asert/" target="_blank" rel="noopener
noreferrer"><img style="border-radius:50%;height:48px;width:auto"
src="img/paulk-asert.png" alt="Paul King"></a>
<div style="display:grid;align-items:center;margin:0.1ex;padding:0ex">
<div><a href="https://github.com/paulk-asert/" target="_blank" rel="noopener
noreferrer"><span>Paul King</span></a></div>
<div><small><i>PMC Member</i></small></div>
</div>
- </div><br/><span>Published: 2026-03-27 04:30PM (Last updated:
2026-04-06 11:35PM)</span></p><hr/><div class="sect1">
+ </div><br/><span>Published: 2026-03-27 04:30PM (Last updated:
2026-07-12 12:00AM)</span></p><hr/><div class="sect1">
<h2 id="_introduction">Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
@@ -652,28 +652,28 @@ or thread-safe types from
<code>java.util.concurrent</code>.</p>
</div>
</div>
<div class="sect1">
-<h2 id="_how_it_relates_to_gpars_and_virtual_threads">How it relates to GPars
and virtual threads</h2>
+<h2 id="_how_it_relates_to_groovy_concurrent_and_gpars">How it relates to
groovy.concurrent and GPars</h2>
<div class="sectionbody">
<div class="paragraph">
-<p>Readers of the
-<a href="https://groovy.apache.org/blog/gpars-meets-virtual-threads">GPars
meets virtual threads</a>
-blog post will recall that GPars provides parallel collections,
-actors, agents, and dataflow concurrency.</p>
-</div>
-<div class="paragraph">
-<p>Async/await complements GPars rather than replacing it. GPars
-excels at data-parallel operations and actor-based designs.
-Async/await targets sequential-looking code that is actually
-asynchronous, with language-level support for streams, cleanup,
-structured concurrency, and framework bridging.</p>
+<p>Async/await is one part of Groovy 6’s broader concurrency toolkit.
The same
+<code>groovy.concurrent</code> package also provides parallel collections,
actors, agents,
+dataflow variables, and Go-style channels (GEP-18), and they all compose with
+the <code>await</code> and <code>Awaitable</code> combinators shown above — so
you build solutions
+from one consistent toolkit rather than learning separate APIs.</p>
</div>
<div class="paragraph">
-<p>GPars' <code>callAsync()</code> and <code>asyncFun()</code> return futures
that work
-naturally with <code>await</code> and the <code>Awaitable</code> combinators,
so you
-can mix and match both styles in the same codebase.</p>
+<p>Before Groovy 6, these features weren’t built in and the
+<a href="http://www.gpars.org/">GPars</a> library was the popular choice for
parallel
+collections, actors, agents, and dataflow. The
+<a href="https://groovy.apache.org/blog/gpars-meets-virtual-threads">GPars
meets virtual threads</a>
+post shows those GPars features. If you are on Groovy 6 or later, prefer the
+built-in <code>groovy.concurrent</code> equivalents; GPars remains useful for
earlier
+Groovy versions and existing GPars codebases. GPars' <code>callAsync()</code>
and
+<code>asyncFun()</code> return futures that work naturally with
<code>await</code> and the <code>Awaitable</code>
+combinators, so you can mix and match both styles during a migration.</p>
</div>
<div class="paragraph">
-<p>Both approaches benefit from virtual threads on JDK 21+.</p>
+<p>All of these approaches benefit from virtual threads on JDK 21+.</p>
</div>
</div>
</div>
@@ -720,7 +720,8 @@ concurrent — not the method signature.</p>
<div class="title">Update history</div>
<div class="paragraph">
<p><strong>27/Mar/2026</strong>: Initial version.<br>
-<strong>06/Apr/2026</strong>: Revised version after feedback including
numerous simplifications.</p>
+<strong>06/Apr/2026</strong>: Revised version after feedback including
numerous simplifications.<br>
+<strong>12/Jul/2026</strong>: Reframe the GPars section around the built-in
<code>groovy.concurrent</code> package.</p>
</div>
</div>
</div>
diff --git a/blog/groovy-list-processing-cheat-sheet.html
b/blog/groovy-list-processing-cheat-sheet.html
index 591ced17..f5e7f310 100644
--- a/blog/groovy-list-processing-cheat-sheet.html
+++ b/blog/groovy-list-processing-cheat-sheet.html
@@ -63,7 +63,7 @@
</ul>
</div>
</div>
- </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>Groovy™ List Processing Cheat Sheet</a></li><li><a
href='#_declaring_lists' class='anchor-link'>Declaring lists</a></li><li><a
href='#_list_elements_and_properties' class='anchor-link'>List elements and
properties</a></li><li><a href='#_modifying_mutable_lists' class [...]
+ </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>Groovy™ List Processing Cheat Sheet</a></li><li><a
href='#_declaring_lists' class='anchor-link'>Declaring lists</a></li><li><a
href='#_list_elements_and_properties' class='anchor-link'>List elements and
properties</a></li><li><a href='#_modifying_mutable_lists' class [...]
<h2 id="_declaring_lists">Declaring lists</h2>
<div class="sectionbody">
<div class="paragraph">
diff --git a/blog/groovy-pekko-gpars.html b/blog/groovy-pekko-gpars.html
index 50b5c7cd..e9a51d7f 100644
--- a/blog/groovy-pekko-gpars.html
+++ b/blog/groovy-pekko-gpars.html
@@ -3,7 +3,7 @@
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--><head>
- <meta charset='utf-8'/><meta http-equiv='X-UA-Compatible'
content='IE=edge'/><meta name='viewport' content='width=device-width,
initial-scale=1'/><meta name='keywords' content='concurrency, groovy, actors,
pekko, gpars'/><meta name='description' content='This post looks at using
Apache Pekko Actors and GPars Actors with Groovy.'/><title>The Apache Groovy
programming language - Blogs - Using Apache Pekko actors and GPars actors with
Groovy™</title><link href='../img/favicon.ico' [...]
+ <meta charset='utf-8'/><meta http-equiv='X-UA-Compatible'
content='IE=edge'/><meta name='viewport' content='width=device-width,
initial-scale=1'/><meta name='keywords' content='concurrency, groovy, actors,
pekko, groovy.concurrent, gpars'/><meta name='description' content='This post
looks at using Apache Pekko Actors and Groovy 6's built-in
groovy.concurrent Actors.'/><title>The Apache Groovy programming language -
Blogs - Using Apache Pekko actors and Groovy™ 6 actors</ti [...]
</head><body>
<div id='fork-me'>
<a href='https://github.com/apache/groovy'>
@@ -63,7 +63,7 @@
</ul>
</div>
</div>
- </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>Using Apache Pekko actors and GPars actors with
Groovy™</a></li><li><a href='#_the_example' class='anchor-link'>The
example</a></li><li><a href='#_a_pekko_implementation_in_groovy'
class='anchor-link'>A Pekko implementation in Groovy</a></li><li><a
href='#_a_gpars_im [...]
+ </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3'><ul
class='nav-sidebar'><li><a href='./'>Blog index</a></li><li class='active'><a
href='#doc'>Using Apache Pekko actors and Groovy™ 6 actors</a></li><li><a
href='#_the_example' class='anchor-link'>The example</a></li><li><a
href='#_a_pekko_implementation_in_groovy' class='anchor-link'>A Pekko
implementation in Groovy</a></li><li><a href='#_a_groovy_6_implemen [...]
<div class="sectionbody">
<div class="paragraph">
<p><span class="image right"><img
src="https://pekko.apache.org/assets/images/pekko_logo.png" alt="pekko logo"
width="100"></span>
@@ -75,14 +75,32 @@ It provides Scala and Java APIs/DSLs for writing your
applications. We’ll
We’ll look at just one example of using Pekko actors.</p>
</div>
<div class="paragraph">
-<p><span class="image right"><img src="./img/gpars_logo.png" alt="gpars"
width="180"></span>
-By way of comparison, we’ll also be looking at <a
href="http://www.gpars.org/">GPars</a>,
-a concurrency library for Java and Groovy with support for actors, agents,
-concurrent & parallel map/reduce, fork/join, asynchronous closures,
dataflow, and more.
-A <a
href="https://groovy.apache.org/blog/gpars-meets-virtual-threads">previous blog
post</a>
-looks at additional features of GPars and how to use it with virtual threads.
+<p>By way of comparison, we’ll also look at the actor support built into
+<strong>Groovy 6</strong> in the <code>groovy.concurrent</code> package
(GEP-18). Alongside actors,
+that package provides agents, dataflow variables, Go-style channels, and
+parallel collections — all virtual-thread-first and composable with
Groovy’s
+<a
href="https://groovy.apache.org/blog/groovy-async-await"><code>async</code>/<code>await</code></a>
support.
Here, we’ll just look at the comparable actor features for our Pekko
example.</p>
</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>Before Groovy 6, these actor features weren’t built in and the
+<a href="http://www.gpars.org/">GPars</a> library was the popular choice. If
you are on an
+earlier Groovy version or maintaining an existing GPars codebase, the
+<a href="https://groovy.apache.org/blog/gpars-meets-virtual-threads">GPars
meets virtual
+threads</a> post shows the equivalent GPars examples. The companion repository
+includes a legacy GPars version of this example too.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
</div>
</div>
<div class="sect1">
@@ -126,8 +144,8 @@ to tell it the maximum number of times to echo the message
before stopping.</p>
<h2 id="_a_pekko_implementation_in_groovy">A Pekko implementation in
Groovy</h2>
<div class="sectionbody">
<div class="paragraph">
-<p>This example uses Groovy 4.0.23 and Pekko 1.1.1.
-It was tested with JDK 11, 17, 21 and 23.</p>
+<p>This example uses Groovy 6.0.0-alpha-2 and Pekko 1.6.0.
+It was tested with JDK 21 and 25.</p>
</div>
<div class="paragraph">
<p>The Pekko documentation gives Java and Scala implementations.
@@ -289,112 +307,106 @@ system.tell(new
HelloWorldMain.SayHello('Pekko'))</code></pre>
</div>
</div>
<div class="sect1">
-<h2 id="_a_gpars_implementation_in_groovy">A GPars implementation in
Groovy</h2>
+<h2 id="_a_groovy_6_implementation_using_groovy_concurrent">A Groovy 6
implementation using groovy.concurrent</h2>
<div class="sectionbody">
<div class="paragraph">
-<p>This example uses Groovy 4.0.23 and GPars 1.2.1.
-It was tested with JDK 8, 11, 17, 21 and 23.</p>
+<p>Groovy 6 ships a native concurrency toolkit in the
<code>groovy.concurrent</code>
+package (GEP-18). Among other features, it provides lightweight,
+virtual-thread-friendly actors that compose with Groovy’s
+<a
href="https://groovy.apache.org/blog/groovy-async-await"><code>async</code>/<code>await</code></a>
support.</p>
</div>
<div class="paragraph">
-<p>We’ll follow the same conventions for strongly typed messages in our
GPars example.
-Here are our three message containers:</p>
+<p>We’ll follow the same conventions for strongly typed messages.
+Because our actors reference one another, we parameterize each
<code>Actor</code> with the
+message type it accepts. Here are our three message records:</p>
</div>
<div class="listingblock">
<div class="content">
-<pre class="prettyprint highlight"><code data-lang="groovy">record
Greet(String whom, Actor replyTo) { }
+<pre class="prettyprint highlight"><code data-lang="groovy">import
groovy.concurrent.Actor
+
+record Greet(String whom, Actor<Greeted> replyTo) { }
-record Greeted(String whom, Actor from) {}
+record Greeted(String whom, Actor<Greet> from) { }
record SayHello(String name) { }</code></pre>
</div>
</div>
<div class="paragraph">
-<p>Now we’ll define our <code>helloWorld</code> actor:</p>
+<p>Now we’ll define our <code>greeter</code> actor. A <em>reactor</em>
actor is stateless: its
+closure handles each incoming message. Here we don’t need to reply
directly,
+so we send a <code>Greeted</code> message on to the reply address
ourselves:</p>
</div>
<div class="listingblock">
<div class="content">
-<pre class="prettyprint highlight"><code data-lang="groovy">greeter = actor {
- loop {
- react { Greet command ->
- println "Hello $command.whom!"
- command.replyTo << new Greeted(command.whom, greeter)
- }
- }
+<pre class="prettyprint highlight"><code data-lang="groovy">Actor<Greet>
greeter
+greeter = Actor.reactor { Greet command ->
+ println "Hello $command.whom!"
+ command.replyTo.send(new Greeted(command.whom, greeter))
}</code></pre>
</div>
</div>
<div class="paragraph">
-<p>Here, we are using GPars Groovy continuation-style DSL for defining actors.
-The <code>loop</code> indicates that the actor will loop continually.
-When we receive the <code>Greet</code> message, we log the details to stdout
and
-send the acknowledgement.</p>
-</div>
-<div class="paragraph">
-<p>If we don’t want to use the DSL syntax, we can use the related
classes directly.
-Here we’ll define a <code>HelloWorldBot</code> using this slightly more
verbose style.
-It shows adding the state variables we need for tracking the invocation
count:</p>
+<p>Our bot needs to remember how many greetings it has seen, so we use a
+<em>stateful</em> actor. We seed it with an initial state of <code>0</code>;
the handler
+receives the current state and the message, and returns the next state:</p>
</div>
<div class="listingblock">
<div class="content">
-<pre class="prettyprint highlight"><code data-lang="groovy">class
HelloWorldBot extends DefaultActor {
- int max
- private int greetingCounter = 0
-
- @Override
- protected void act() {
- loop {
- react { Greeted message ->
- greetingCounter++
- println "Greeting $greetingCounter for $message.whom"
- if (greetingCounter < max) message.from << new
Greet(message.whom, this)
- else terminate()
- }
- }
+<pre class="prettyprint highlight"><code data-lang="groovy">def newBot = { int
max ->
+ Actor<Greeted> bot
+ bot = Actor.stateful(0) { int count, Greeted message ->
+ int next = count + 1
+ println "Greeting $next for $message.whom"
+ if (next < max) message.from.send(new Greet(message.whom, bot))
+ else bot.stop()
+ next
}
+ bot
}</code></pre>
</div>
</div>
<div class="paragraph">
-<p>Our main actor is very simple. It is waiting for <code>SayHello</code>
messages, and when it receives one,
-it sends the payload to the helloWorld greeter telling it to reply to a newly
created <em>bot</em>.</p>
+<p>Our main actor is very simple. It waits for <code>SayHello</code> messages,
and when it receives one,
+it sends the payload to the greeter, telling it to reply to a newly created
<em>bot</em>.</p>
</div>
<div class="listingblock">
<div class="content">
-<pre class="prettyprint highlight"><code data-lang="groovy">var main = actor {
- loop {
- react { SayHello command ->
- greeter << new Greet(command.name, new HelloWorldBot(max:
3).start())
- }
- }
+<pre class="prettyprint highlight"><code data-lang="groovy">def main =
Actor.reactor { SayHello command ->
+ greeter.send(new Greet(command.name, newBot(3)))
}</code></pre>
</div>
</div>
<div class="paragraph">
-<p>Finally, we start the system going by sending some initial messages:</p>
+<p>Finally, we start the system going by sending some initial messages,
+give the actors a moment to finish, then stop them:</p>
</div>
<div class="listingblock">
<div class="content">
-<pre class="prettyprint highlight"><code data-lang="groovy">main << new
SayHello('World')
-main << new SayHello('GPars')</code></pre>
+<pre class="prettyprint highlight"><code data-lang="groovy">main.send(new
SayHello('World'))
+main.send(new SayHello('Groovy 6'))
+
+sleep 2000
+main.stop()
+greeter.stop()</code></pre>
</div>
</div>
<div class="paragraph">
-<p>The output looks like this:</p>
+<p>The output looks like this (the exact interleaving varies between runs):</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Hello World!
-Hello GPars!
+Hello Groovy 6!
+Greeting 1 for Groovy 6
Greeting 1 for World
-Greeting 1 for GPars
+Hello Groovy 6!
Hello World!
-Hello GPars!
+Greeting 2 for Groovy 6
+Hello Groovy 6!
Greeting 2 for World
+Greeting 3 for Groovy 6
Hello World!
-Greeting 2 for GPars
-Hello GPars!
-Greeting 3 for World
-Greeting 3 for GPars</pre>
+Greeting 3 for World</pre>
</div>
</div>
</div>
@@ -403,49 +415,40 @@ Greeting 3 for GPars</pre>
<h2 id="_discussion">Discussion</h2>
<div class="sectionbody">
<div class="paragraph">
-<p>The GPars implementation is less verbose compared to the Pekko
implementation but Pekko
-is known for providing additional type safety for actor messages and that is
partly what we are seeing.</p>
+<p>The <code>groovy.concurrent</code> implementation is less verbose than the
Pekko
+implementation. Pekko is known for providing additional type safety for
+actor messages, and that is partly what we saw in the Pekko version, where
+each actor is a <code>Behavior<T></code> for a specific message type.
Pekko also brings a
+much larger feature set — clustering, persistence, streams, and distribution —
+so it remains the right choice when you need those capabilities.</p>
</div>
<div class="paragraph">
-<p>GPars supports a mixture of styles, some offering less verbosity at the
expense of capturing some
-errors at runtime rather than compile-time. Such code can be useful when
wanting very succinct code
-using Groovy’s dynamic nature. When using Groovy’s static nature
or Java, you might consider using
-select parts of the GPars API.</p>
+<p>The core Groovy actors are typed too: an <code>Actor<Greet></code>
only accepts <code>Greet</code>
+messages, so message sends are checked when you compile statically (for example
+with <code>@CompileStatic</code> or <code>@TypeChecked</code>) while remaining
convenient for dynamic
+Groovy. You choose between a stateless <code>Actor.reactor</code> and a
stateful
+<code>Actor.stateful</code> depending on whether the actor needs to remember
anything
+between messages.</p>
</div>
<div class="paragraph">
-<p>For example, we can provide an alternative definition for
<code>HelloWorldBot</code> like this:</p>
+<p>Because core actors integrate with <code>async</code>/<code>await</code>,
request/reply is
+straightforward. Rather than wiring up an explicit reply address, a reactor can
+simply <em>return</em> a value and the caller can <code>await</code> the reply
from <code>sendAndGet</code>:</p>
</div>
<div class="listingblock">
<div class="content">
-<pre class="prettyprint highlight"><code data-lang="groovy">class
HelloWorldBot extends StaticDispatchActor<Greeted> {
- int max
- private int greetingCounter = 0
-
- @Override
- void onMessage(Greeted message) {
- greetingCounter++
- println "Greeting $greetingCounter for $message.whom"
- if (greetingCounter < max) message.from << new
Greet(message.whom, this)
- else terminate()
- }
-}</code></pre>
-</div>
-</div>
-<div class="paragraph">
-<p>The <code>StaticDispatchActor</code> dispatches the message solely based on
the compile-time information.
-This can be more efficient when dispatching based on message run-time type is
not necessary.</p>
-</div>
-<div class="paragraph">
-<p>We could also provide an alternative definition for <code>Greet</code> as
follows:</p>
-</div>
-<div class="listingblock">
-<div class="content">
-<pre class="prettyprint highlight"><code data-lang="groovy">record
Greet(String whom, StaticDispatchActor<Greeted> replyTo) { }</code></pre>
+<pre class="prettyprint highlight"><code data-lang="groovy">def doubler =
Actor.reactor { it * 2 }
+assert await(doubler.sendAndGet(21)) == 42
+doubler.stop()</code></pre>
</div>
</div>
<div class="paragraph">
-<p>With changes like these in place we can code a solution with additional
message type safety
-when using Groovy’s static nature.</p>
+<p>The same building blocks — agents, dataflow variables, channels, and
parallel
+collections — all live in <code>groovy.concurrent</code> and compose with the
same
+async/await combinators, so you build up solutions from a single, consistent
+toolkit rather than learning separate APIs. See the
+<a href="https://groovy.apache.org/blog/groovy-async-await">Async/await for
Groovy</a> post
+for the bigger picture.</p>
</div>
</div>
</div>
@@ -453,7 +456,8 @@ when using Groovy’s static nature.</p>
<h2 id="_conclusion">Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
-<p>We have had a quick glimpse at using actors with Apache Pekko and GPars.</p>
+<p>We have had a quick glimpse at using actors with Apache Pekko and with
Groovy 6’s
+built-in <code>groovy.concurrent</code> package (with GPars noted as the
pre-Groovy-6 option).</p>
</div>
<div class="paragraph">
<p>The sample code can be found here:</p>
@@ -461,6 +465,9 @@ when using Groovy’s static nature.</p>
<div class="paragraph">
<p><a href="https://github.com/paulk-asert/groovy-pekko-gpars"
class="bare">https://github.com/paulk-asert/groovy-pekko-gpars</a></p>
</div>
+<div class="paragraph">
+<p>It contains <code>pekko</code>, <code>groovy6</code>, and legacy
<code>gpars</code> versions of the example.</p>
+</div>
<div class="sidebarblock">
<div class="content">
<div class="title">Update history</div>
@@ -469,7 +476,8 @@ when using Groovy’s static nature.</p>
<strong>18/Jul/2023</strong>: Add discussion about type-safe messages.<br>
<strong>26/Jul/2023</strong>: Update to Pekko 1.0.1.<br>
<strong>25/Jun/2024</strong>: Update to Pekko 1.0.3.<br>
-<strong>28/Sep/2024</strong>: Update to Pekko 1.1.1.</p>
+<strong>28/Sep/2024</strong>: Update to Pekko 1.1.1.<br>
+<strong>12/Jul/2026</strong>: Update to Pekko 1.6.0 and Groovy 6; replace the
GPars example with the built-in <code>groovy.concurrent</code> actors (GPars
retained as a legacy reference).</p>
</div>
</div>
</div>
diff --git a/blog/index.html b/blog/index.html
index 1c1997f2..8611b2a4 100644
--- a/blog/index.html
+++ b/blog/index.html
@@ -63,7 +63,7 @@
</ul>
</div>
</div>
- </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3' id='blog-index'><ul
class='nav-sidebar list'><li class='active'><a
href='/blog/'>Blogs</a></li><li><a href='groovy6-formal-methods'>Groovy 6
features for formal method advocates</a></li><li><a
href='multimodal-universe-with-groovy'>Exploring the Multimodal Universe with
Groovy™</a></li><li><a href='fizzbuzz-with-groovy-and-emojis'>FizzBuzz
with Groovy and Emo [...]
+ </div><div id='content' class='page-1'><div
class='row'><div class='row-fluid'><div class='col-lg-3' id='blog-index'><ul
class='nav-sidebar list'><li class='active'><a
href='/blog/'>Blogs</a></li><li><a href='gpars-meets-virtual-threads'>GPars
meets Virtual Threads</a></li><li><a href='groovy-pekko-gpars'>Using Apache
Pekko actors and Groovy™ 6 actors</a></li><li><a
href='groovy-async-await'>Async/await for Groovy™</a></li><li><a
href='groovy6-formal-m [...]
<div class='row'>
<div class='colset-3-footer'>
<div class='col-1'>
@@ -107,7 +107,7 @@
colors: am5.ColorSet.new(root, {})
}));
wc.data.setAll([
- { category: "groovy", value: 93 }, { category: "asf", value: 2
}, { category: "apachecon", value: 3 }, { category: "communityovercode", value:
2 }, { category: "natural language processing", value: 2 }, { category: "nlp",
value: 1 }, { category: "nlpcraft", value: 1 }, { category: "combinations",
value: 1 }, { category: "permutations", value: 1 }, { category: "testing",
value: 2 }, { category: "junit", value: 2 }, { category: "spock", value: 2 }, {
category: "jqwik", valu [...]
+ { category: "groovy", value: 93 }, { category: "asf", value: 2
}, { category: "apachecon", value: 3 }, { category: "communityovercode", value:
2 }, { category: "natural language processing", value: 2 }, { category: "nlp",
value: 1 }, { category: "nlpcraft", value: 1 }, { category: "combinations",
value: 1 }, { category: "permutations", value: 1 }, { category: "testing",
value: 2 }, { category: "junit", value: 2 }, { category: "spock", value: 2 }, {
category: "jqwik", valu [...]
]);
wc.labels.template.setAll({
paddingTop: 5,
diff --git a/search/search-index.json b/search/search-index.json
index acb9f01c..ff39e163 100644
--- a/search/search-index.json
+++ b/search/search-index.json
@@ -212,7 +212,7 @@
{
"id": "blog/groovy-list-processing-cheat-sheet.html",
"title": "The Apache Groovy programming language - Blogs -
Groovy™ List Processing Cheat Sheet",
- "content": "The Apache Groovy programming language - Blogs -
Groovy™ List Processing Cheat Sheet Socialize Discuss on the mailing list
Groovy on X Groovy on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and
conferences Source code on GitHub Report issues in Jira Stack Overflow
questions Slack Community You are using an outdated browser. Please upgrade
your browser to improve your experience. Apache Groovy™ Learn
Documentation Download Support Contribute Ecosyst [...]
+ "content": "The Apache Groovy programming language - Blogs -
Groovy™ List Processing Cheat Sheet Socialize Discuss on the mailing list
Groovy on X Groovy on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and
conferences Source code on GitHub Report issues in Jira Stack Overflow
questions Slack Community You are using an outdated browser. Please upgrade
your browser to improve your experience. Apache Groovy™ Learn
Documentation Download Support Contribute Ecosyst [...]
"url": "blog/groovy-list-processing-cheat-sheet.html",
"site": "dev"
},
@@ -275,7 +275,7 @@
{
"id": "blog/groovy-async-await.html",
"title": "The Apache Groovy programming language - Blogs - Async/await
for Groovy™",
- "content": "The Apache Groovy programming language - Blogs -
Async/await for Groovy™ Socialize Discuss on the mailing list Groovy on X
Groovy on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and conferences
Source code on GitHub Report issues in Jira Stack Overflow questions Slack
Community You are using an outdated browser. Please upgrade your browser to
improve your experience. Apache Groovy™ Learn Documentation Download
Support Contribute Ecosystem Blog post [...]
+ "content": "The Apache Groovy programming language - Blogs -
Async/await for Groovy™ Socialize Discuss on the mailing list Groovy on X
Groovy on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and conferences
Source code on GitHub Report issues in Jira Stack Overflow questions Slack
Community You are using an outdated browser. Please upgrade your browser to
improve your experience. Apache Groovy™ Learn Documentation Download
Support Contribute Ecosystem Blog post [...]
"url": "blog/groovy-async-await.html",
"site": "dev"
},
@@ -400,8 +400,8 @@
},
{
"id": "blog/groovy-pekko-gpars.html",
- "title": "The Apache Groovy programming language - Blogs - Using
Apache Pekko actors and GPars actors with Groovy™",
- "content": "The Apache Groovy programming language - Blogs - Using
Apache Pekko actors and GPars actors with Groovy™ Socialize Discuss on
the mailing list Groovy on X Groovy on Bluesky Groovy on Mastodon Groovy on
LinkedIn Events and conferences Source code on GitHub Report issues in Jira
Stack Overflow questions Slack Community You are using an outdated browser.
Please upgrade your browser to improve your experience. Apache Groovy™
Learn Documentation Download Suppor [...]
+ "title": "The Apache Groovy programming language - Blogs - Using
Apache Pekko actors and Groovy™ 6 actors",
+ "content": "The Apache Groovy programming language - Blogs - Using
Apache Pekko actors and Groovy™ 6 actors Socialize Discuss on the mailing
list Groovy on X Groovy on Bluesky Groovy on Mastodon Groovy on LinkedIn Events
and conferences Source code on GitHub Report issues in Jira Stack Overflow
questions Slack Community You are using an outdated browser. Please upgrade
your browser to improve your experience. Apache Groovy™ Learn
Documentation Download Support Contrib [...]
"url": "blog/groovy-pekko-gpars.html",
"site": "dev"
},
@@ -569,14 +569,14 @@
{
"id": "blog/fizzbuzz-with-groovy-and-emojis.html",
"title": "The Apache Groovy programming language - Blogs - FizzBuzz
with Groovy and Emojis",
- "content": "The Apache Groovy programming language - Blogs - FizzBuzz
with Groovy and Emojis Socialize Discuss on the mailing list Groovy on X Groovy
on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and conferences Source
code on GitHub Report issues in Jira Stack Overflow questions Slack Community
You are using an outdated browser. Please upgrade your browser to improve your
experience. Apache Groovy™ Learn Documentation Download Support
Contribute Ecosystem Blog po [...]
+ "content": "The Apache Groovy programming language - Blogs - FizzBuzz
with Groovy and Emojis Socialize Discuss on the mailing list Groovy on X Groovy
on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and conferences Source
code on GitHub Report issues in Jira Stack Overflow questions Slack Community
You are using an outdated browser. Please upgrade your browser to improve your
experience. Apache Groovy™ Learn Documentation Download Support
Contribute Ecosystem Blog po [...]
"url": "blog/fizzbuzz-with-groovy-and-emojis.html",
"site": "dev"
},
{
"id": "blog/gpars-meets-virtual-threads.html",
"title": "The Apache Groovy programming language - Blogs - GPars meets
Virtual Threads",
- "content": "The Apache Groovy programming language - Blogs - GPars
meets Virtual Threads Socialize Discuss on the mailing list Groovy on X Groovy
on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and conferences Source
code on GitHub Report issues in Jira Stack Overflow questions Slack Community
You are using an outdated browser. Please upgrade your browser to improve your
experience. Apache Groovy™ Learn Documentation Download Support
Contribute Ecosystem Blog posts [...]
+ "content": "The Apache Groovy programming language - Blogs - GPars
meets Virtual Threads Socialize Discuss on the mailing list Groovy on X Groovy
on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and conferences Source
code on GitHub Report issues in Jira Stack Overflow questions Slack Community
You are using an outdated browser. Please upgrade your browser to improve your
experience. Apache Groovy™ Learn Documentation Download Support
Contribute Ecosystem Blog posts [...]
"url": "blog/gpars-meets-virtual-threads.html",
"site": "dev"
},
@@ -730,7 +730,7 @@
{
"id": "blog/index.html",
"title": "The Apache Groovy programming language - Blogs",
- "content": "The Apache Groovy programming language - Blogs Socialize
Discuss on the mailing list Groovy on X Groovy on Bluesky Groovy on Mastodon
Groovy on LinkedIn Events and conferences Source code on GitHub Report issues
in Jira Stack Overflow questions Slack Community You are using an outdated
browser. Please upgrade your browser to improve your experience. Apache
Groovy™ Learn Documentation Download Support Contribute Ecosystem Blog
posts Socialize Blogs Groovy 6 featu [...]
+ "content": "The Apache Groovy programming language - Blogs Socialize
Discuss on the mailing list Groovy on X Groovy on Bluesky Groovy on Mastodon
Groovy on LinkedIn Events and conferences Source code on GitHub Report issues
in Jira Stack Overflow questions Slack Community You are using an outdated
browser. Please upgrade your browser to improve your experience. Apache
Groovy™ Learn Documentation Download Support Contribute Ecosystem Blog
posts Socialize Blogs GPars meets Vi [...]
"url": "blog/index.html",
"site": "dev"
},