ProgrammingPro #73: Java Microservices, C Falls in Tiobe Index, Rust Firmware Deployment, and Protocol Buffer Design
Welcome to this week’s edition of ProgrammingPro!
In today’s Expert Insight, we bring you an excerpt from the recently published book, Java Concurrency and Parallelism, which demonstrates building a data processing pipeline using a microservices architecture with Java.
News Highlights: C language falls to its lowest position in the Tiobe index; TypeScript 5.6 adds new compiler options and diagnostics; Vapor 5 leverages Swift 6 concurrency; and Rust 1.81 stabilizes the Error trait.
My top 5 picks from today’s learning resources:
Modernize your UWP app with preview UWP support for .NET 9 and Native AOT🚀
Protocol Buffer Design - Principles and Practices for Collaborative Development🤝
Mastering Impact Analysis and Optimizing Change Release Processes🛠️
But there’s more, so dive right in.
Stay Awesome!
Divya Anne Selvaraj
Editor-in-Chief
PS: This month’s survey is still live. Do take the opportunity to tell us what you think of ProgrammingPro, request learning resources, and earn your one Packt Credit for this month.
🗞️News and Analysis🔎
C language slumps in Tiobe popularity index: C has dropped to fourth place, its lowest position since the index began. Read to learn about the reasons for C's reduced popularity compared to alternatives like C++ and Rust.
.NET 9 Release Candidate 1 is now available!: Key updates include enhanced WebSocket APIs, new compression options (ZLib and Brotli), advanced SignalR tracing, and improvements to .NET MAUI.
Vapor 5 Materializes the Future of Server-Side Development in Swift: The release will leverage Swift 6's structured concurrency, introduce modern packages, and rewrite WebSocket and MultipartKit APIs for better async.
Rust 1.81 stabilizes Error trait: The update allows its use in
#![no_std]libraries, and introduces improved sort algorithms for better performance.TypeScript 5.6 now generally available: The update includes features such as disallowing nullish and truthy checks on non-variable syntax, new compiler options, and improved diagnostics.
JFrog helps developers improve DevSecOps with new solutions and integrations: JFrog announced new solutions and integrations with GitHub and NVIDIA at its swampUp conference, enhancing security capabilities.
Express.js 5.0 released after long delay, though not yet default as project appeals for contributors: New features include improved path route matching, better error handling for rejected promises, and the return of the app.router.
🎓Tutorials and Learning Resources💡
Sponsored Mini Course on AI worth $399 for free: 200+ hours of research on AI-led career growth strategies & hacks packed in 3 hours. Register Now.
Python
Python QuickStart for People Learning AI: Covers Python fundamentals, including data types, loops, and functions, and provides a concrete AI project example using the OpenAI API for summarizing research papers.
For more Python resources, go to PythonPro
C# and .NET
🎓Tutorial | Modernize your UWP app with preview UWP support for .NET 9 and Native AOT: Explains how to upgrade UWP apps incrementally to .NET 9, adopt Native AOT, and discusses tools for future migration to WinUI 3.
WebAssembly and Containers: Orchestrating Distributed Architectures with .NET AspireLike: Explains how .NET Aspire simplifies orchestration using C#, enabling developers to manage components using the Dashboard.
🎓Tutorial | C# Testing set up: Provides a step-by-step guide on setting up testing in C# using xUnit, with a focus on creating a basic test structure for a C# class.
C and C++
What’s new in C++26 (part 1): Focuses on specifying reasons for deleted functions, unnamed placeholder variables, structured binding declarations in conditions, and user-generated static_assert messages.
🎓Tutorial | Giving C++ std::regex a C makeover: Discusses how to wrap C++'s
std::regexinto a C interface, providing a way to use C++ regular expressions in C projects without dealing with C++ directly.🎥💼Case Study | Zero-Cost Abstractions in C++ - High Performance Message Dispatch - Luke Valenty - C++Now 2024: Provides a detailed breakdown of how Intel optimizes message handling and uses C++ techniques to manage power in embedded systems.
Java
🎓Tutorial | Packages and static imports in Java: Explains how Java developers can use packages and static imports to organize top-level types, prevent naming conflicts, and simplify access to static members.
🎓Tutorial | Using oneAPI Construction Kit and TornadoVM to accelerate Java Programs on x86, ARM and RISC-V CPUs: Covers setup, performance comparisons, and configurations for OCK as an OpenCL and SPIR-V driver.
🎓Tutorial | Writing a Linux scheduler in Java with eBPF (15): Explains how to implement two Linux schedulers using eBPF in Java: a FIFO scheduler and a weighted scheduler.
Recent Java Resources from Packt
Discover strategies and best practices to develop high performance Java applications
Get the eBook for $33.99 $22.99
Proven recipes for building modern and robust Java web applications with Spring Boot
Get the eBook for $31.99 $21.99
Master Continuous Integration with Jenkins: Automate, Test, and Deploy Like a Pro
Get the 3 hour course for $49.99
JavaScript and TypeScript
Understanding Concurrency, Parallelism and JS: Explores the differences between concurrency and parallelism, explains how JavaScript achieves concurrency through Node.js’s single-threaded event-driven model, and more.
Javascript/Python Array Quick Reference: Offers side-by-side comparisons of syntax for tasks like accessing, iterating, mapping, adding/removing elements, filtering, and sorting.
What Good Looks Like - A Real-World Typescript Refactor: Demonstrates a real-world TypeScript refactor of an entity-manager library, focusing on improving efficiency and reducing complexity.
Go
🎓Tutorial | An HTTP Server in Go From scratch: Walks through key steps, including binding to a port, responding with status codes, extracting URL paths, handling request headers, and implementing concurrent connections.
Using Go instead of bash for scripts: Explains how to automate programming tasks and simplify development by replacing Bash scripts with a more efficient, cross-platform Go program.
Rust
Deploying Rust in Existing Firmware Codebases: Discusses how to incrementally deploy Rust into existing firmware codebases, focusing on enhancing memory safety, especially for critical components.
Porting C to Rust for a Fast and Safe AV1 Media Decoder: Takes you through the challenges and methods of preserving C API compatibility, managing threading models, and achieving memory safety while maintaining performance.
Swift
Swift Type placeholder - What is it and when to use it: Discusses Swift's type placeholders, introduced in Swift 5.6, allowing the compiler to infer complex types using underscores (_) in place of specific types.
Swift Testing - Validate your code using expressive APIs: Discusses Apple's new Swift Testing framework, which includes the @Test macro for defining tests, the #expect macro for assertions, and enhanced feedback in Xcode for test results.
PHP
🎓Look out, kids - PHP is the new JavaScript: Shows how Laravel has revitalized PHP, offering developers an easy and efficient way to build dynamic web applications, making PHP fun and relevant again.
SQL
Dissecting a Hybrid Search query in SQL: Explains how to use Common Table Expressions (CTEs) in SQL to build hybrid search queries, focusing on combining vector and full-text search results.
Kotlin
Loading Initial Data in LaunchedEffect vs. ViewModel: Compares two approaches for loading initial data in Jetpack Compose: using
LaunchedEffectwithin a composable andViewModel.init().
🌟Best Practices and Advice🚀
💼Case Study | Protocol Buffer Design - Principles and Practices for Collaborative Development: Highlights the benefits of Protobuf for scalability, backward compatibility, and consistency in multi-language environments.
How to Make Technical Debt Your Friend: Argues that not all TD needs to be repaid, and using a Minimum Viable Architecture (MVA) approach allows teams to focus on delivering Minimum Viable Products that meet immediate needs.
Mastering Impact Analysis and Optimizing Change Release Processes: Emphasizes focusing on "why" rather than "who" when analyzing failures, improving pre-production testing, and minimizing the blast radius of bugs.
Do we need enterprise software marketplaces?: Explores the evolution of marketplaces, from gadget collections to API-driven models, and the importance of maintaining strong vendor relationships for future success.
🧠Expert Insight📚
Here’s an excerpt from “Chapter 8: Microservices in the Cloud and Java’s Concurrency” in the book, Java Concurrency and Parallelism, by Jay Wang, published in August 2024.
Use case 2 – building a data processing pipeline with microservices
This case study delves into designing and implementing a data processing pipeline using a microservices architecture:
The first step is to design the microservices. We’ll construct the pipeline with three distinct microservices:
Data ingestion service: This service acts as the entry point, which is responsible for receiving and validating incoming data from external sources. Once validated, it publishes the data to an Amazon SQS queue for further processing. The service depends on the Amazon SQS client library.
Data processing service: This service subscribes to the Amazon SQS queue used by the data ingestion service. It consumes the data, applies business logic for transformation, and publishes the processed data to another SQS queue for persistence. This service relies on both the Amazon SQS client library and the AWS Glue SDK.
Data persistence service: The final service consumes the processed data from the second SQS queue. Its primary function is to store the data persistently in Amazon RDS for long-term accessibility. This service utilizes both the Amazon SQS client library and the Amazon RDS client library...
The next step is to set up the AWSs:
Two AWS Simple Queue Service (SQS) queues will be set up:
Initial data queue: Create a queue intended for receiving initial unprocessed data
Processed data queue: Set up another queue for holding processed data ready for further actions or storage
AWS RDS instance: Set up an RDS instance to provide persistent storage for your application. You can choose MySQL, PostgreSQL, or any other available RDS database engine depending on your application requirements. This database will be used to store and manage the data processed by your application.
AWS Simple Notification Service (SNS): Create an SNS topic to facilitate the notification process. This topic will be used to publish messages notifying subscribers of successful data processing events and other important notifications. Determine the subscribers to this topic, which could include email addresses, SMS, HTTP endpoints, or even other AWS services such as Lambda or SQS, depending on your notification requirements.
The third step is to set up a Maven project. Create a new Maven project for each microservice (DataIngestionService, DataProcessingLambda, and DataPersistenceService) in your preferred Integrated Development Environment (IDE) or using the command line. Open the
pom.xmlfile in each project’s root directory and add the related dependencies.The fourth step is to implement the data ingestion service:
@Service
public class DataIngestionService {
private final AmazonSQS sqsClient;
public DataIngestionService(AmazonSQS sqsClient) {
this.sqsClient = sqsClient;
}
public void ingestData(Data dat{
// Validate the incoming data
if (isValid(data)) {
// Publish the data to Amazon SQS
SendMessageRequest sendMessageRequest = new SendMessageRequest()
.withQueueUrl("data-ingestion-queue-url")
.withMessageBody(data.toString());
sqsClient.sendMessage(sendMessageRequest);
}
}
private boolean isValid(Data dat{
boolean isValid = true;
// Implement data validation logic
// ...
return isValid;
}
The code represents the implementation of the data ingestion service, which is responsible for receiving incoming data, validating it, and publishing it to Amazon SQS for further processing.
The DataIngestionService class is annotated with @Service , indicating that it is a Spring service component. It has a dependency on the AmazonSQS client , which is injected through the constructor.
The ingestData() method takes a data object as input and performs data validation by calling the isValid() method. If the data is valid, it creates a SendMessageRequest object with the specified SQS queue URL and the data payload as the message body. The message is then sent to the SQS queue using the sqsClient.sendMessage() method.
The fifth step is to implement the data processing service using AWS Lambda:
public class DataProcessingLambda implements RequestHandler<SQSEvent, Void> {
private final AmazonSQS sqsClient;
public DataProcessingLambda() {
this.sqsClient = AmazonSQSClientBuilder.defaultClient();
}
@Override
public Void handleRequest(SQSEvent event,
Context context) {
for (SQSEvent.SQSMessage message :
event.getRecords()) {
String data = message.getBody();
// Transform the data within the Lambda function
String transformedData= transformData(
data);
// Publish the transformed data to another Amazon SQS for persistence or further
// processing
sqsClient.sendMessage(
new SendMessageRequest()
.withQueueUrl(
"processed-data-queue-url")
.withMessageBody(transformedData));
}
return null;
}
/**
* Simulate data transformation.
* In a real scenario, this method would contain logic to transform data based
* on specific rules or operations.
*
* @param data the original data from the SQS message
* @return transformed data as a String
*/
private String transformData(String dat{
// Example transformation: append a timestamp or modify the string in some way
return "Transformed: " + data + " at " + System. currentTimeMillis();
}
}
This Lambda function, DataProcessingLambda , processes data from an Amazon SQS queue by implementing the RequestHandler interface to handle SQSEvent events. It initializes an Amazon SQS client in the constructor and uses it to send transformed data to another SQS queue for further processing or storage.
The handleRequest() method, serving as the function’s entry point, processes each SQSMessage from the SQSEvent , extracting the data and transforming it directly within the function through the transformData() method. Here, the transformation appends a timestamp to the data as a simple example, but typically this would involve more complex operations tailored to specific data processing requirements.
Following the data transformation, the function sends the processed data to a specified SQS queue by invoking the sendMessage() method on the SQS client.
The next step is to create a Spring-managed service that handles storing processed data in a database and notifies subscribers via AWS SNS upon successful persistence:
@Service
public class DataPersistenceService {
private final AmazonSNS snsClient;
private final DataRepository dataRepository;
public DataPersistenceService(DataRepository dataRepository) {
// Initialize the AmazonSNS client
this.snsClient = AmazonSNSClientBuilder.standard(). build();
this.dataRepository = dataRepository;
}
public void persistData(String data{
// Assume 'data' is the processed data received
// Store the processed data in a database
Data dataEntity = new Data();
dataEntity.setProcessedData(data);
dataRepository.save(dataEntity);
// Send notification via SNS after successful persistence
sendNotification("Data has been successfully persisted with the following content: " + data);
}
private void sendNotification(String message) {
// Define the ARN of the SNS topic to send notification to
String topicArn = "arn:aws:sns:region:account-id:your- topic-name";
// Create the publish request
PublishRequest publishRequest = new PublishRequest()
.withTopicArn(topicArn)
.withMessage(message);
// Publish the message to the SNS topic
snsClient.publish(publishRequest);
}
}
DataPersistenceService is a Spring-managed bean responsible for handling data persistence and notifying other components or services via Amazon SNS....
Java Concurrency and Parallelism was published in August 2024. Packt library subscribers can continue reading the entire book for free or you can buy the book here!
Get the eBook for $33.99 $22.99
🛠️Useful Tools⚒️
dokku: an open-source PaaS using Docker, allowing developers to deploy Heroku-compatible apps via git and run them in isolated containers.
R3: a modern, high-performance reimplementation of Reactive Extensions for .NET, optimized for game engines and aligned with new C# features.
nomadic: An enterprise-grade toolkit by NomadicML for optimizing compound AI systems, allowing teams to refine hyperparameters and prompts.
That’s all for today.
We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most useful here. Complete ProgrammingPro archives can be found here. Complete PythonPro archives are here.
If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want to advertise with us.







