JP Camara's Avatar

JP Camara

@jpcamara.com

Principal software engineer @Wealthbox. Husband/Father. Health, travel, tech and Ruby enthusiast. Tech blog at https://jpcamara.com Jokes at https://logicalconclusionscomic.com

1,313
Followers
764
Following
656
Posts
21.09.2024
Joined
Posts Following

Latest posts by JP Camara @jpcamara.com

Preview
Allow retry_on wait procs to accept error as a second argument by jpcamara · Pull Request #56601 · rails/rails Motivation / Background Currently, retry_on wait procs can only accept the execution count as an argument, which limits the ability to customize retry delays based on the error itself. Some excepti...

Currently in ActiveJob, `wait` in `retry_on` accepts a proc, but it is only handed the execution count. I think access to the error can also be useful when calculating the next wait time. If you agree, give it a like! github.com/rails/rails/...

13.01.2026 22:04 👍 6 🔁 1 💬 1 📌 0
Ad for “it’s 10pm do you know where you children are?”

Ad for “it’s 10pm do you know where you children are?”

Ad for “it’s 10pm do you know where you children are?”, but with “children” overwritten by “threads”

Ad for “it’s 10pm do you know where you children are?”, but with “children” overwritten by “threads”

“It’s 10pm, do you know where your children are?”

I added this to my “when good threads go bad” post

Does anyone else remember these ads?! May have only been a USA thing

31.12.2025 15:35 👍 7 🔁 0 💬 1 📌 0

Yea I didn’t want to `raise` any suspicions with such a long gap between posts, but sometimes in life you’ve just got to `handle_interrupt`s 😜

31.12.2025 15:32 👍 2 🔁 0 💬 0 📌 0

Finally got it released, just before the new year 🥲

30.12.2025 21:14 👍 5 🔁 0 💬 1 📌 0
Preview
When good threads go bad 👋🏼 This is part of series on concurrency, parallelism and asynchronous programming in Ruby. It’s a deep dive, so it’s divided into several parts: Your Ruby programs are always multi-threaded: Part 1 ...

It’s late, and you get alerts that web requests are failing. Page loads hang endlessly. The server isn’t responding, requests are queueing up. What do you do?!

"When good threads go bad" is a deep dive into stuck threads, how to deal with them, and what to avoid.

jpcamara.com/2025/12/30/w...

30.12.2025 21:10 👍 12 🔁 2 💬 1 📌 0
Preview
a man with a beard and long hair looks surprised ALT: a man with a beard and long hair looks surprised
30.12.2025 13:32 👍 2 🔁 0 💬 0 📌 0

🙇‍♂️ 🙇‍♂️ 🙇‍♂️

27.12.2025 15:32 👍 7 🔁 0 💬 0 📌 0

Awesome! Can you say which one??

27.12.2025 15:30 👍 2 🔁 0 💬 0 📌 0
JP Camara, Real-time collaboration with Rails, AnyCable and Yjs. San Francisco Ruby Conference 2025.
JP Camara, Real-time collaboration with Rails, AnyCable and Yjs. San Francisco Ruby Conference 2025. YouTube video by Evil Martians

My @sfruby.com talk on real-time collaboration with AnyCable, YJS and Rails is up! I felt really happy with how it came out - let me know what you think because I can't watch myself talk 😂
youtu.be/J68QOBLEItY

26.12.2025 22:49 👍 15 🔁 2 💬 1 📌 1
Post image

TIL if you want to return the duration in seconds, returning it as an Integer is a _hard_ requirement

There is a _specific_ check that the class is Integer. If you accidentally return a float, Sidekiq ignores it and reverts to its built-in delay policy. Be careful!

19.12.2025 03:47 👍 3 🔁 0 💬 1 📌 0
Post image

In Sidekiq, you can add a special method to your job class called `sidekiq_retry_in`. This method allows you to dynamically adjust retry behavior. For instance, based on the exception raised you can return a different duration in seconds. /1

19.12.2025 03:47 👍 12 🔁 0 💬 2 📌 0

It's actually happening! Gonna super busy for the next 139 days. 😄

12.12.2025 16:18 👍 17 🔁 2 💬 1 📌 0
Post image

@sfruby.com Day 3 was the perfect community break!
Started with a Lucasfilm museum walk (thank you, @inazarova.bsky.social), then joined the Golden Gate Bridge bike tour with @kanejamison.com, @jpcamara.com, @jeremysmith.co, @adarsh.ruby.social.ap.brid.gy and so many amazing Rubyists.

05.12.2025 15:44 👍 9 🔁 2 💬 0 📌 0
Post image Post image Post image Post image

Had an incredible time at @sfruby.com
Fantastic talks, amazing people, and great vibes across the board
So much to dig into and unpack around tooling, AI, development patterns and our collective ownership in the future of Rails
Community day was such a great finish

22.11.2025 19:27 👍 19 🔁 2 💬 0 📌 0
Post image

I'm not sure @ankane.bsky.social is human - maybe some kind of open source being from the future 😂
I said to a colleague - "we'll see, but it's ankane, so it's entirely possible it'll get done soon". Less than an hour later, it was updated 🤯

12.11.2025 01:18 👍 17 🔁 1 💬 0 📌 0
Preview
a pixel art of a heart with the words ruby time written on it ALT: a pixel art of a heart with the words ruby time written on it
11.11.2025 16:19 👍 3 🔁 0 💬 0 📌 0

Also very curious! I was big into warp for a while, but a) they literally still don't support full terminal history and cap at 20k lines and b) feels like they're getting further and further from prioritizing the actual terminal part
i'm back on iterm2 again, but i'd love a better tool

10.11.2025 13:25 👍 1 🔁 0 💬 2 📌 0

If you are anywhere near SF Ruby Conf and haven't bought a ticket yet, the time is now! This conf is gonna be 🔥🔥🔥

10.11.2025 13:23 👍 8 🔁 2 💬 0 📌 0

ok nice to know you are still human 😂😂😂!

02.11.2025 19:41 👍 2 🔁 0 💬 0 📌 0

Amazing, thanks for putting a name to it @byroot.bsky.social ! I'm gonna dig into this more

02.11.2025 19:08 👍 0 🔁 0 💬 0 📌 0

"Today I ran Brussels half marathon and it was 21.1km of pure joy!"

I have never heard a marathon described as "pure joy" 😂 It must have truly been something special!

02.11.2025 19:04 👍 1 🔁 0 💬 1 📌 0

Thanks for the reference! I'm gonna check this out more. Zeitwerk is something I think would be super interesting to read through - I bet there's some unique stuff you've had to do in there

02.11.2025 19:03 👍 1 🔁 0 💬 0 📌 0
Post image

4) "When good threads go bad" coming soon!

Dan shows how jobs are executed in the `process` method, which has this hefty section utilizing `handle_interrupt`. He does a great job describing how it works, and my next article will dig deeper into if you're interested!

11/11 🧵

02.11.2025 02:27 👍 2 🔁 1 💬 0 📌 0
Post image

If you read my article on ruby thread interrupts and bitmasks, this will be very familiar! jpcamara.com/2025/10/22/b...

I asked koichi if signals were the inspiration, and he confirmed it. It was fun to see the connection and what can be an inspiration for central language apis!

10/11 🧵

02.11.2025 02:27 👍 1 🔁 0 💬 1 📌 0

3) The design of Ruby thread interrupts seem heavily influenced by linux signals

When referring to the linux signal docs, I noticed a startling resemblance - it included `raise` and `kill` functions, a list of pending signals, and a way to block signals using bitmasks with pthread_sigmask

9/11 🧵

02.11.2025 02:27 👍 0 🔁 0 💬 1 📌 0

`compare_by_identity` sets the hash to compare keys by their reference instead of their value. Not day-to-day useful but a fascinating option, and utilized nicely in Sidekiq

8/11 🧵

02.11.2025 02:27 👍 0 🔁 0 💬 2 📌 0
Post image

You can change the default return value of a hash by using `default=` on the hash. docs.ruby-lang.org/en/3.4/Hash..... Now instead of nil, you'll return whatever `default` you provided! Very handy.

7/11 🧵

02.11.2025 02:27 👍 0 🔁 0 💬 1 📌 0

`handle_signal` can do what it wants! No reentrancy requirements! No special requirements at all in fact - we're back in the regular flow of our program! Super clever.

2) Two weird hash methods big Hash doesn't want you to know...

6/11 🧵

02.11.2025 02:27 👍 1 🔁 0 💬 1 📌 0

Meanwhile, the main loop for sidekiq is always waiting on the io reader, calling a blocking method, `wait_readable` in the while loop. Signal received -> write the signal -> wait_readable returns truthy -> while loop runs and calls `handle_signal` with the signal read

5/11 🧵

02.11.2025 02:27 👍 1 🔁 0 💬 1 📌 0
signals - Documentation for Ruby 3.4 signals: Caveats for implementing Signal. trap callbacks As with implementing signal handlers in C or most other languages, all code passed to Signal.

The full reasons for that are explained in docs.ruby-lang.org/en/3.4/signa..., and have to do with a concept called "reentrancy".

But mike bypasses all of that by using using IO.pipe. The io writer is safe to write to in the trap, so that's all it does, it writes the signal.

4/11 🧵

02.11.2025 02:27 👍 1 🔁 0 💬 1 📌 0