Claude Moore

+ Follow
since Jun 24, 2005
Claude likes ...
IBM DB2 Netbeans IDE Spring Java
Merit badge: grant badges
For More
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Rancher Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Claude Moore

Also, please note that messages are a well known pattern to handle effectively workload balancing. You may define a Queue and having a number of listener on that queue: MOM ensures that only a single instance will receive a message pushed to a queue, so that you can easily add enpoints for you business scenario. Of course, several complex architectural  schemas exist.
1 week ago
You should not need any thread at all, just register all JMSEndpoint and let the spring framework handle incoming messages in a concurrent way for you.
Have a look at official documentation on the topic
With respect to your second question, we'll, the only answer I can give you is : it depends on how are you going to process incoming messages.
Generally speaking, all MOMs scale very well, and also do Java Runtime. If a message triggers a business transaction, the actual workload will depends upon how long a single transaction can last and how much CPU / RAM it may consume, or if it's blocking (it access data and so on). Keep in mind that any incoming message is processed asynchrounously, in a separated thread, handled by Spring - again, no need for Executors.

1 week ago
Generally speaking,  it's undoubtly true that a lot of hype is all around AI nowadays.
Despite this, achievements in the fields are also undoubtly game-changers, at least for the possibilities AI may open.
Personally, I think we're far away from Gen-AI; nevertheless, current AI achievements are comparable to invention of electronic calculators years ago.
Hi Mark,
hope you're doing great, and thank you for being here on the ranch!
Generative AI as far as I know requires huge computational power. What are minimal HW requirements to experiment with it, following examples and tips you teach in your book ?
All the best!
Just googled a bit about debuggin lambda in local ide, found this in AWS documentation.
It's about a lambda written in Python, I think that any other supported language / framework could be debugged locally as well.
1 month ago

Lou Hamers wrote:

Yes that's why I like to call it ML instead of AI. But I still end up using the "AI" term sometimes, because I guess we already lost that battle. EVERYONE is calling it AI and most people don't know what "ML" is. Intelligence means thinking, to me, and this software isn't doing that.

Right, ML is a field of AI, but are often threated as synonims. And that's conceptually wrong.

Lou Hamers wrote:
My main worry about this stuff currently is that it ends up too centralized and controlled. I'd much rather see it open source, accessible to all for a low cost, and hosted locally without needing to rely on some corporate spy company. Theoretically that would help level the playing field for the little guys against increasingly powerful and wealthy organizations/people.

Please consider that training you own model at a state of the art level  would imply spending A LOT of money per day, something that only Big IT Firms can really afford.  If you want to play with a local version of ChatGPT, you may have a look at GPT4All : it's a tool that lets you to download a free LLM model and run it locally. Of course, we're far away from GPT4, but it could gave you a glimpse of what you can do with AI powered bots in your own business.

Lou Hamers wrote:Makes sense, but I hope whatever's written in Python gets implemented in other languages eventually.

Python quickly become the de facto language for ML for two main reasons: first, it's a simple yet effective language, and it doesn't require a long training to learn as much as you need to approach ML, which is essentially math.
Second, scikit-learn library is a excellent library for scientific calculations, and its' effective also in contexts rather different from ML: it's gained a widespread adoption in many research fields. Moreover, using tools like Jupyter Noteboook, you can quickly experiment and prototype a working solution, that you may want to run on Google Colab, for example.
Please note that I'm talking about DOING ML, not about USING ML for somewhat project: using poweful AI / ML Models we all know - like OpenAI for example or Gemini - is a task you can accomplish with whatever language you want, as long as your preferred language can execute REST API calls.

Tim Holloway wrote:It's what those third hands are touching that make me hesitant. And the funny fingers. We're still learning about machine learning.

ML is still a research field, and despite the fact that deep learning has reached unforeseable goals, we're still far from a General AI.  IMHO what AI based programmers' assistant tools (and the word 'tool' isn't casual here) is to help programmers write basilar code, no more no less like a calculator helps anyone to make, well, calculations. But Math itself is something by far more complex than calculate sums and products.
Solution you described - with a bit of humor I really appreciated, by the way - is more or less the solution I've adopted. Basically, I create a TransactionLock entity which primary key is derived from keys of actual entities involved in the process -the invoice or the shipping you mentioned.A TransactionLock is @Versioned, so that if two operators decided to work contemporarily on the same flow, well, there will be a winner that will take it all and a loser, that will need to start over the activity -and honestly, maybe to learn how to coordinate itself with coworkers.
Anyway this solution, honestly thought as a modest workaround, looked to me quite general, and I wondered if it could be taken as a convenient approach to handle concurrency in general way.But I soon realized that despite the fact it works, isn't anything more than a patch put there to solve a design severe error: to properly handle that, there should have been some master entity that drove the transaction - an entity to apply properly a lock strategy.
Thanks for your help, and have a cow !
2 months ago
Indeed,in the current code the major flaw I can see it's that there is no way to prevent two transactions to update the state of the same entity, preventing
them to override updates each other. The example you made about attempting to insert a duplicated key in a database is very clear, while, at the same time, says nothing about actual order of execution of two concurrent transactions. We only know that if A commits before B, B is rolled back. In my (flawed) scenario, there wasn't anything like a duplicated key exception to the rescue. Just for example, suppose that I have a Purchase order, with an unique PO number as  ID. How could I prevent that two operators could handle totally differently the very same order? Suppose that the order has a status and the picking procedure starts by setting that status to "preparing",only when current status is "ready", while a "cancel" procedure sets it to "cancelled" .Actual race condition was:
A reads the picking with status ready
B reads the picking with status ready (no select for update here)
A updates picking state to "preparing"
A commits
B updates picking state to "cancelled"
B commits.
There's nothing here preventing such a mess, and @Transactional could do nothing by itself.
So, you could either use an optimistic lock or a pessimistic lock, the latter preventing dirty reads with a proper isolation level and a select for update on the picking record: but in this case, transaction B should be aborted immediately if the lock can't be acquired or check manually for entity status once the lock has been acquired. Otherwise, if it waits and doesn't check, the same problem may arise.
Am I correct?
2 months ago
First of all, thanks Tim for your reply.

Tim Holloway wrote:Just to be clear, I'm taking it as a given that you're NOT attempting to do any sort of threading here, that these are, in fact, multiple concurrent client requests. Because although it may not be apparent, most of the business logic in a Spring Boot app runs under a Servlet or JSP and both of those are absolutely forbidden to spawn threads.

Correct, I'm not starting manual threads anywhere: anyway, concurrent requests handling very same object may happen. The whole scenario is that before I optimized @Service code responsible to handle the business transaction, an user had to wait about 1.5 minutes (!!) before the transaction completes. Somehow, an user managed to execute the very same request twice in a really short time (we actually think that the web UI allowed them to execute some kind of double click). The result was: whole transaction executed twice.

Tim Holloway wrote:
As far as database locking goes, my understanding of Optimistic Locking in JPA is that before an update is posted the JPA infrasstructure does a fetch of the affected record(s) and checks to make sure no one has modified them elsewhere, throwing an Exception if they have. Been there/done that.

My own database logic, which I've often mentioned elsewhere on the Ranch has essentially 3 layers.

*  The Entity Layer, which (surprise!) defines the table and View Entity classes.
* The DAO Layer, which is primarily concerned with CRUD and finders for individual tables, or tightly-bound parent-child table pairs. Lately Spring Data's repository feature has supplanted a lot of the brute-force logic for me.
* The Service Layer. This layer works on a "working set" of related records (a directed graph). It detaches the graph from the JPA system before returning a fetched set to the higher levels of the app and it re-attaches (merges) when the business levels request a Service method to update the datastore. The Service layer delegates its dirty work to the DAOs.

Both the Service Layer and DAO layer classes are marked @Transactional,wwhere the DAO transactions get adopted into the transaction of the service that uses them (I forget the exact name of that option, though).

I'd say it's a textbook solution...

Tim Holloway wrote:
Once a Service is bound in a Transaction, it will either queue behind other Transactions or throw a locking Exception if it cannot otherwise resolve matters. In the case of a lock exception, the service is going to have to re-think its own changes to whatever Entities had conflicting requests and resolve them before trying again. Which sounds intimidating, but isn't something I've had many problems with.

Well, this should depend actually on isolation level of the transaction, but i don't think it it's enough to prevent lost updates without some kind of checking on data. Suppose two distinct transactions are trying to perform some kind of action on a given entity at the same time:  a possible scenario is the following:
a) Tx A tries a SELECT FOR UPDATE on entity  and gets the lock;
b) Tx B tries a SELECT FOR UPDATE on the same entity and waits for some time before getting a Locking Timeout or something similar;
c) Tx A commits the transaction and releases the lock
d) Tx B is granted the lock on the entity, and commits, overriding data set by transaction A.

At the very end,  one needs to thread some business transactions as not-repeatable, and to use some property (a status of the entity, for example, to mark it as "processed"), but this not a job that a framework may accomplish by its own. A solution may be to throwing a LockingException immediately, and rollback the transaction.

Anyway my question was about a pattern to follow whenever you cannot add a @Version attribute to an entity for any reason. The approach I followed was to use an "OptimisticLock" entity which unique key is derived by the actual entity being persisted, and work on @Version field of the wrapping an OptimisticLock.

To be honest, I think that is the entity  design is flawed and it would be wise to fix it before it's too late.

2 months ago
I'm tackling a project, based on Spring Boot, where a number of entities - each of which can have other entities of different types connected - must be processed simultaneously in the same session. The list of and entities to be processed is passed as requests to a REST API. In some - rare cases, it may happen that a duplicate request of the same processing is executed; To handle cases like these, where the chances of having two transactions processing the same data set are low, using the Optimistic Lock Strategy is recommended. This pattern assumes that entities are versioned, i.e. they have a field annotated with @Version. I'm just wondering if someone tried to apply somewhat similar to decorator pattern to this approach, i.e, using a "wrapper versioned entity" which wraps the actual, unversioned entity, exposing a @Version field and having an ID derived from wrapped entity ID.
Thanks in advance.
2 months ago
Thanks Carey for sharing your experience. Some colleagues of mine are quite afraid that AI in general will replace programmers.
For me, it isn't a fear I feel. My point of view is that at the current state of the art (and, reasonably, for a very long time, until a different approach will be found to create and train a real general AI), tools like chat GPT and alike will follow the same destiny which was followed by calculators: calculators let humas to rid of calculations made by hand, AI tools will avoid human programmers to write by hand tons of code.
I think that your way of using AI as a code helper will be a common work scenario in the days to come.
What do you think about ?
Hi there,

for professional reasons I need to grasp a solid knowledge on C#, .NET at software architect level. Currently, I've a strong knowledge in Java / Spring and architectures written in Java; I believe that while the concepts are pretty the same (patterns are patterns, the language you use to implement software doesn't really matter), using C# and .NET fluently and idiomatically isn't so automatic at all.
Which path of study do you suggest me to follow ?  Which prerequisites I need to fulfill ?
Thanks in advance.
9 months ago