artem
Hi all
I am learning CQRS and Commanded by doing a project (so main point is learning), I’ve got to the point where it is already doing something useful on my laptop: you type a news article and then it uses ChatGPT for crafting some clever posts about it + you can tune the response with supposedly cool UI.
Now I want to make it public and let people play with it for free, but within some limits so I don’t get bankrupt on a hobby project (say, some 20-50 generations for user per month or per whole user lifetime) and.. how do you do it in CQRS? ![]()
Non-CQRS ways
I come from Java/SpringBoot world so a relatively natural way for me would be to have some sort of credits field in the customer or user object. Then before doing something expensive (ChatGPT generation in this case) I’d check if there are credits available and decrease them in the same transaction. If generation fails, then some fail handler may or may not reuse credit back.
Ways for CQRS and specifically commanded
As everything in CQRS is eventually consistent, does it mean that I need to “book” some credits, make it somehow possible to monitor when the “booking” is completed (via some projection with a booking request id?) and only then do a request?
Or is possible to rely on Commanded’s strong consistency (or maybe it’s enough to specify option returning: aggregate_state when dispatching) and once dispatch has happened I can already know if the credits were enough or not.
Or am I missing some other obvious options? Like is it possibly common for exactly “credit checks” kind of use cases live outside CQRS so that DB transactions could be used for consistency protections and access serialization?
Again, my main point here is learning (though I still want to open project to public), so I’ll highly appreciate any hints and ideas, especially if ever did anything like that in CQRS.
P.S.
Even though it’s mostly self-education project almost invented just so I could have a real use case to play with CQRS, there is still some reasoning for exactly CQRS. My main technical motivation is about separating read-write models so I could have as many and as convenient read models as I like. Access serialization and consistency are way less important for me in this particular case.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #blog-post
- #ai
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 1- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
byu
Caveat: I’m a major beginner in EventSourcing and CQRS.
What about something like the following?
generation-account-bob-202402SubmitGenerationCommandthat includesSubmitGenerationCommandcan emit EventsGenerationSubmittedEvent– with request identifierGenerationRequestRejectedEvent– with details such as:GenerationSubmittedEventand then issue commands or execute API requests?Basically, requests go into a “rate limiter” aggregate for that user-period. The Events of Submitted/Completed/Failed/Rejected requests allow the single aggregate to track the used credits count, pending credits such that
used credits + pending <= allowed credits? and can reject requests over the limit?And follow-on Event Handlers will eventual consistently process (succeed or fail) the submitted requests?
The above uses patterns:
We avoid:
[edit]: Here’s a suggested video that also talks about how to do different kinds of “business transactions” that spans multiple streams: