This is standard practice on monolithic apps. It is effectively an N-tier architecture. On Rails it is very expected that you would deploy the same codebase to two tiers (web and worker) and simply run rails s in one and sidekiq in the other.
Keep the monolith, but split the workloads
61–70 of 161 posts
Re: Keep the monolith, but split the workloads
#62Earlier quoted context omitted.
Have you worked with Go codebases before? Standard practice is to wrap all your entrypoints - the start of a web request, the moment you begin to run a job - in a defer recover() which will catch panics. Sadly, recover won’t apply to any subsequently goroutine’d work. That means even if your entrypoints recover, if anything go func()s down the call stack, then if that function then panics it will bring down the entir…
I probably misunderstand what you wrote. Because I think a (wrapped) panic will only result in crashing the one request that caused it? For example Gin provides a middleware wrapper for handling panics: CustomRecoveryWithWriter returns a middleware for a given writer that recovers from any panics and calls the provided handle func to handle it. ( https://github.com/gin-gonic/gin/blob/master/recovery.go )
It gives some code examples and explanations that should clear this up: https://incident.io/blog/intermittent-downtime#mitigation-1-...
^ link should go to the relevant section
Re: Keep the monolith, but split the workloads
#63Earlier quoted context omitted.
Ditto in Django + Celery
Anyone using a more modern/lightweight alternative to Celery?
[0] https://python-rq.org/ [1] https://github.com/rq/django-rq [2] https://github.com/rq/rq-scheduler
Re: Keep the monolith, but split the workloads
#64I quite like the article and the advice it presents, building what I'd call modular monoliths (that can have modules be enabled or disabled based on feature flags) is indeed a good approach for both increasing resiliency and decreasing the blast radius of various issues. However, this bit stuck out to me: > When a bad Pub/Sub message was pulled into the binary, an unhandled panic would crash the entire app, meaning w…
Have you worked with Go codebases before? Standard practice is to wrap all your entrypoints - the start of a web request, the moment you begin to run a job - in a defer recover() which will catch panics. Sadly, recover won’t apply to any subsequently goroutine’d work. That means even if your entrypoints recover, if anything go func()s down the call stack, then if that function then panics it will bring down the entir…
Re: Keep the monolith, but split the workloads
#65I quite like the article and the advice it presents, building what I'd call modular monoliths (that can have modules be enabled or disabled based on feature flags) is indeed a good approach for both increasing resiliency and decreasing the blast radius of various issues. However, this bit stuck out to me: > When a bad Pub/Sub message was pulled into the binary, an unhandled panic would crash the entire app, meaning w…
The most dangerous kinds of mistakes in that area are bugs or oversights that cause massive resource usage or endless loops. Those can easily bring down parts of the application that are otherwise robustly separated in the way you mentioned. Consuming too much memory will kill the app at some point, just using lots of CPU or IO will make everything else grind to a halt. Holding onto resources that are pooled like DB…
Each request would need to work with one or more of them. There was a cache, and the code was written to avoid a thundering herd. But in the case where the data was corrupt, an exception was thrown, and nothing was put in the cache. So the application sat dedicating multiple cores to a cycle of loading and parsing these data files then errorring out.
Re: Keep the monolith, but split the workloads
#66Earlier quoted context omitted.
Do you think it's good idea to migrate from monolith to microservices before scaling the team? We are essentially doing this right now, I personally don't think the teams are yet large enough to warrant this migration, but leadership says that we can't scale further before we have microservices. Imo most of the problems could be solved with increased testing and knowledge about the system. The tech also could definit…
Are you doing “extreme” micro services? A esperare database for each micro service, one endpoint for each microservice etc.. or the slightly more sensible - let’s split the monolith up into obviously independent system (very much like the article talks about).
>separate databases
Isnt it like the basic thing?
Re: Keep the monolith, but split the workloads
#67SOA, sure (hello CICS :-)).
DB sharding if needed for load / resources.
Otherwise logical division into sets of related services that can be their own little monolith or go full monorepo.
Perhaps I'm missing something …
Re: Keep the monolith, but split the workloads
#68Earlier quoted context omitted.
Have you worked with Go codebases before? Standard practice is to wrap all your entrypoints - the start of a web request, the moment you begin to run a job - in a defer recover() which will catch panics. Sadly, recover won’t apply to any subsequently goroutine’d work. That means even if your entrypoints recover, if anything go func()s down the call stack, then if that function then panics it will bring down the entir…
To me, it's unclear what the best solution is here. Other languages solve this differently with tradeoffs, e.g. Java defaults to threads silently dying when an exception isn't caught. Your program will continue to run, but it's probably in some undefined state at that point. There are mechanisms for propagating exceptions elsewhere, but they have to be explicitly set up (like in Go). You can set a default uncaught ex…
Re: Keep the monolith, but split the workloads
#69Earlier quoted context omitted.
Anyone using a more modern/lightweight alternative to Celery?
We use RQ[0], it has Redis as a dependency. It’s pretty straightforward and we’re very happy with it. If you are using Django you may want to look at Django RQ[1] as well. RQ has built in scheduling capabilities these days, but historically it did not so we used (and still use) RQ Scheduler[2] which I think still has some advantages over the built in stuff. [0] https://python-rq.org/ [1] https://github.com/rq/django-…
Re: Keep the monolith, but split the workloads
#70Earlier quoted context omitted.
Anyone using a more modern/lightweight alternative to Celery?
Yes, dramatiq is quite good, but I ditched it for something even more lightweight -- pubsub subscribers via push notification so workers are web workers responding to http requests that might take up to 10 minutes