Skip to content

Commit

Permalink
Fix some tags
Browse files Browse the repository at this point in the history
(and unfortunately, opened the files with VSCode which trimmed the lines)
  • Loading branch information
gsmet committed Apr 18, 2024
1 parent d790114 commit 0215db2
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 45 deletions.
38 changes: 19 additions & 19 deletions _posts/2020-11-02-quarkus-native-on-a-raspberry-pi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: post
title: 'Quarkus native running on a Raspberry Pi'
date: 2020-11-02
tags: armv8 arm raspberrypi native
tags: arm raspberrypi native
synopsis: Running a Quarkus native app inside a container on a Raspberry Pi
author: abattagl
---
Expand All @@ -18,9 +18,9 @@ To achieve the above goal, I’ve picked up a single-board computer with an inte

## Prerequisites

* *Single-board computer:* The ARM-compatible CPU integrated into the single-board computer must support 64-bit mode.
* *Single-board computer:* The ARM-compatible CPU integrated into the single-board computer must support 64-bit mode.

* *Operating system:*
* *Operating system:*
** To make a Quarkus native container image run in a container, a 64-bit Linux OS is required;

** The OS must support aarch64 CPUs, which leads us to the need for an aarch64-base distribution available for that OS;
Expand All @@ -29,7 +29,7 @@ To achieve the above goal, I’ve picked up a single-board computer with an inte

* *Container technology:* surprise, surprise! an OCI standard container engine is compulsory to run containers on Linux :-)

* *Build tools:* as per the large amount of resources required by the GraalVM to compile Quarkus in native mode, an additional we need an ARM server / Virtual machine to achieve that goal. The server should meet the following minimum requirements:
* *Build tools:* as per the large amount of resources required by the GraalVM to compile Quarkus in native mode, an additional we need an ARM server / Virtual machine to achieve that goal. The server should meet the following minimum requirements:
** CPU: same ARM model as the one embedded in the target single-board computer
** Cores: 4
** Ram: 8Gb
Expand Down Expand Up @@ -127,7 +127,7 @@ The remote container registry of choice is https://quay.io/[Quay.io]. More detai

## Implementation

This section will guide you through the following
This section will guide you through the following

. Setting up the VM
. Setting up the RPi and Fedora IoT
Expand Down Expand Up @@ -207,7 +207,7 @@ export JAVA_HOME=${GRAALVM_HOME}
export PATH=${GRAALVM_HOME}/bin:$PATH
----

Example:
Example:

[source,]
----
Expand Down Expand Up @@ -343,7 +343,7 @@ $ systemctl stop firewalld

#### Create a new user for the device

Thanks to the fedora-arm-installer tool, we've added out public key to the root user.
Thanks to the fedora-arm-installer tool, we've added out public key to the root user.
Using root user on a linux system is never a good idea or, let’s say, a good practice.
For this reason, we’re going to add a new administrative user with wheel privileges to our OS:

Expand Down Expand Up @@ -478,19 +478,19 @@ This paragraph shows the outcome produced by the above steps:
[edge@localhost ~]$ sudo podman run -it --rm -p 8090:8080 --name quarkus-getting-started quay.io/abattagl/quarkus-getting-started:1-aarch64
Trying to pull quay.io/abattagl/quarkus-getting-started:1-aarch64...
Getting image source signatures
Copying blob d44f88e7704f done
Copying blob 8c4861605060 done
Copying blob c5a0fdbc0d7a done
Copying blob 5dd9a2ffef88 done
Copying config f08559ac50 done
Copying blob d44f88e7704f done
Copying blob 8c4861605060 done
Copying blob c5a0fdbc0d7a done
Copying blob 5dd9a2ffef88 done
Copying config f08559ac50 done
Writing manifest to image destination
Storing signatures
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2020-10-01 08:49:34,566 INFO [io.quarkus] (main) getting-started 1.0-SNAPSHOT native (powered by Quarkus 1.8.1.Final) started in 0.055s. Listening on: http://0.0.0.0:8080
2020-10-01 08:49:34,566 INFO [io.quarkus] (main) Profile prod activated.
2020-10-01 08:49:34,566 INFO [io.quarkus] (main) Profile prod activated.
2020-10-01 08:49:34,566 INFO [io.quarkus] (main) Installed features: [cdi, resteasy]
^C
2020-10-01 08:49:49,061 INFO [io.quarkus] (Shutdown thread) getting-started stopped in 0.007s
Expand Down Expand Up @@ -528,14 +528,14 @@ This article reproduces the steps to compile and run a Quarkus native app on a R

### Building tools

For this PoC I've used a QEmu-base VM. That promotes reusability, but it's still expensive in terms of usability (QEmu works like a charm on linux OS, but not on Windows and MacOS). As stated at the beginning of this article, a more flexible, portable and scalable solution still based on cpu emulation and container technology is under investiogation at the moment. That would help the delegation and scalability of build process.
For this PoC I've used a QEmu-base VM. That promotes reusability, but it's still expensive in terms of usability (QEmu works like a charm on linux OS, but not on Windows and MacOS). As stated at the beginning of this article, a more flexible, portable and scalable solution still based on cpu emulation and container technology is under investiogation at the moment. That would help the delegation and scalability of build process.

Be aware that QEmu-based tools are still a workaround. GraalVM is missing the cross-compile feature and it will take a while to release it.

### Quarkus everywhere

It's clear that Quarkus can potentially run everywhere. It is, of course, a matter of supportability from GraalVM to the underlying architecture.

So far I feel comfortable in stating that this is just the beginning and lots more features and capabilities are yet to come.
So far I feel comfortable in stating that this is just the beginning and lots more features and capabilities are yet to come.

It would very nice to have a distribution of Mandrel for aarch64. Mandrel is aligned with the `native-image` capabilities from GraalVM with OpenJDK and Red Hat Enterprise Linux libraries to improve maintainability. Looking forward to testing it ;-)
4 changes: 2 additions & 2 deletions _posts/2023-07-05-lts-releases.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: post
title: 'Long-Term Support (LTS) for Quarkus'
date: 2023-07-06
tags: announcements
tags: announcement
synopsis: 'We are introducing Quarkus Long Term Support releases, Quarkus 3.2.x will be the first.'
author: maxandersen
---
Expand Down Expand Up @@ -33,7 +33,7 @@ Here's what you need to know as a Quarkus user:

All of the above applies to Quarkus extension maintainers and contributors as well. In addition, we will be recommending that extension maintainers and contributors consider bug fixes and enhancements for LTS releases. This will ensure that LTS releases are as stable and robust as possible.

This means that extension maintainers and contributors will need to consider having branches and versioning in place for LTS releases.
This means that extension maintainers and contributors will need to consider having branches and versioning in place for LTS releases.

Many extensions already have done this in the context of Quarkus 2 to 3 move. For example, Neo4j has a 1.x for Quarkus 2 and a 2.x branch for Quarkus 3. Going forward we will recommend that extensions have a branch for the LTS version (currently 3.2.x) and one for main Quarkus 3 features, a 3.x.

Expand Down
30 changes: 15 additions & 15 deletions _posts/2023-09-25-virtual-threads-3.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
layout: post
title: 'Testing virtual thread applications'
date: 2023-10-02
tags: virtual threads, reactive, test
tags: virtual-threads reactive test
synopsis: 'How to detect pinning while running tests.'
author: cescoffier
---
:imagesdir: /assets/images/posts/virtual-threads

https://quarkus.io/blog/virtual-threads-2/[In a previous post], we have seen how to implement a CRUD application using virtual threads in Quarkus.
https://quarkus.io/blog/virtual-threads-2/[In a previous post], we have seen how to implement a CRUD application using virtual threads in Quarkus.
The following video shows how to test this application and, specifically, how to detect pinning.

+++
Expand All @@ -20,19 +20,19 @@ The complete code of the application and the tests are available in the https://
## Pinning and Monopolization

Virtual threads combine an imperative development model with a reactive execution mode.
It may provide a simple way to increase the concurrency of an application.
It may provide a simple way to increase the concurrency of an application.
However, this might not always be the case.

As described in https://quarkus.io/blog/virtual-thread-1/[another blog post], there are a few limitations, including monopolizing and pinning carrier threads.
When this happens, the application's performance can drastically decrease and increase memory usage.
As described in https://quarkus.io/blog/virtual-thread-1/[another blog post], there are a few limitations, including monopolizing and pinning carrier threads.
When this happens, the application's performance can drastically decrease and increase memory usage.
Pinning for a short period can be tolerated, but it can be dramatic under load.

While, at the moment, there are no reliable ways to detect monopolization, there are mechanisms to detect pinning.

## Printing stack traces when a carrier thread gets pinned

Suppose you have your application, and your code base contains tests.
You can configure Surefire (or the plugin you use to execute your tests) to dump a stack trace as soon as a virtual thread is going to pin the carrier thread (instead of being unmounted smoothly).
You can configure Surefire (or the plugin you use to execute your tests) to dump a stack trace as soon as a virtual thread is going to pin the carrier thread (instead of being unmounted smoothly).
You must set the `jdk.tracePinnedThreads` system property to achieve this.
For the Surefire Maven plugin, add the `argLine` parameter to the configuration:

Expand Down Expand Up @@ -63,9 +63,9 @@ Thread[#141,ForkJoinPool-1-worker-1,5,CarrierThreads]
java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
----

Analyzing the application logs will tell you whether your application is pinning.
Analyzing the application logs will tell you whether your application is pinning.
Furthermore, a closer look at the stack trace will give you the reason.
In our example, the `pinTheCarrierThread` method is taking a lock.
In our example, the `pinTheCarrierThread` method is taking a lock.
This is indicated by the `monitors:1` text:

[source, text]
Expand All @@ -79,10 +79,10 @@ You can also determine how long the carrier thread was blocked by correlating th
## Failing tests

Dumping the stack trace may not be very convenient when your logs are already long.
Fortunately, we released a small Junit 5 extension that allows you to fail the tests when pinning is detected.
It's advantageous when you integrate a third-party library, and you need to know how virtual-thread-friendly it is (to decide between regular worker threads and virtual threads)
Fortunately, we released a small Junit 5 extension that allows you to fail the tests when pinning is detected.
It's advantageous when you integrate a third-party library, and you need to know how virtual-thread-friendly it is (to decide between regular worker threads and virtual threads)

The loom-unit Junit5 extension is currently a separated project.
The loom-unit Junit5 extension is currently a separated project.
We are integrating it into the Quarkus test framework (under the `junit5-virtual-threads` name), so some of the steps mentioned below won't be necessary anymore or will be changed slightly.

To use this extension, make sure you have the loom-unit extension in your project:
Expand All @@ -92,7 +92,7 @@ To use this extension, make sure you have the loom-unit extension in your projec
<dependency>
<groupId>me.escoffier.loom</groupId> <!-- Will become io.quarkus.junit5 -->
<artifactId>loom-unit</artifactId> <!-- Will become junit5-virtual-threads -->
<version>0.3.0</version> <!-- Will become unnecessary -->
<version>0.3.0</version> <!-- Will become unnecessary -->
<scope>test</scope>
</dependency>
----
Expand All @@ -113,13 +113,13 @@ class TodoResourceTest {
Finally, use the `@ShouldNotPin` annotation to indicate to fail the test if any of the methods of the test case pins the carrier thread.
You can also use the `@ShouldNotPin` annotation on methods.

If, during the execution of a test, a pinning event is captured, the test fails.
If, during the execution of a test, a pinning event is captured, the test fails.
The stack trace of the event is attached to the test failure:

[source, text]
----
java.lang.AssertionError: The test testInitialItems() was expected to NOT pin the carrier thread, but we collected 1 event(s)
* Pinning event captured:
* Pinning event captured:
java.lang.VirtualThread.parkOnCarrierThread(java.lang.VirtualThread.java:687)
java.lang.VirtualThread.parkNanos(java.lang.VirtualThread.java:646)
java.lang.VirtualThread.sleepNanos(java.lang.VirtualThread.java:803)
Expand All @@ -145,7 +145,7 @@ Find more about the loom-unit extension on https://github.com/cescoffier/loom-un
## Summary

This blog explains how you can detect pinning events while running your tests.
First, you can dump the stack trace in the log.
First, you can dump the stack trace in the log.
Second, you can use the `@ShouldNotPin` annotation to fail the tests if a pinning event is captured.
Thanks to this https://github.com/quarkusio/quarkus/pull/35992[PR], the loom-unit extension will be integrated into the `@QuarkusTest` to provide a simpler developer experience.
It will be part of Quarkus in the next release (3.5.x).
18 changes: 9 additions & 9 deletions _posts/2023-11-16-quarkus-meets-langchain4j.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: post
title: 'When Quarkus meets LangChain4j'
date: 2023-11-15
tags: AI langchain
tags: ai langchain
synopsis: 'Learn about the new quarkus-langchain4j extension to integrate LLMs in Quarkus applications.'
author: cescoffier
---
Expand Down Expand Up @@ -70,14 +70,14 @@ Speaking about methods, that's where the magic happens. You will describe what y
@RegisterAiService
public interface TriageService {
@SystemMessage("""
You are working for a bank, processing reviews about
financial products. Triage reviews into positive and
You are working for a bank, processing reviews about
financial products. Triage reviews into positive and
negative ones, responding with a JSON document.
"""
)
@UserMessage("""
Your task is to process the review delimited by ---.
Apply sentiment analysis to the review to determine
Apply sentiment analysis to the review to determine
if it is positive or negative, considering various languages.
For example:
Expand All @@ -86,10 +86,10 @@ public interface TriageService {
- `I hate your bank, you are the worst!` is a 'NEGATIVE' review
Respond with a JSON document containing:
- the 'evaluation' key set to 'POSITIVE' if the review is
- the 'evaluation' key set to 'POSITIVE' if the review is
positive, 'NEGATIVE' otherwise
- the 'message' key set to a message thanking or apologizing
to the customer. These messages must be polite and match the
- the 'message' key set to a message thanking or apologizing
to the customer. These messages must be polite and match the
review's language.
---
Expand Down Expand Up @@ -179,7 +179,7 @@ public class ChatMemoryBean implements ChatMemoryProvider {
@Override
public ChatMemory get(Object memoryId) {
return memories.computeIfAbsent(memoryId,
return memories.computeIfAbsent(memoryId,
id -> MessageWindowChatMemory.builder()
.maxMessages(20)
.id(memoryId)
Expand Down Expand Up @@ -232,7 +232,7 @@ public class IngestorExample {
.embeddingStore(store)
.embeddingModel(embeddingModel)
.documentSplitter(recursive(500, 0))
.build();
.build();
ingestor.ingest(documents);
}
}
Expand Down

0 comments on commit 0215db2

Please sign in to comment.