Josh Nichols (@techpickles) header
Josh Nichols (@techpickles) profile picture

Principal Whimsy Engineer for myself, Staff Software Engineer for @GustoHQ. Hobby hobbyist, husband, father, noun, https://teapawt.net/t.co/9L8pwSaRrY . Opinions are my own.

Atlanta, GA
Joined June 2007
Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)Photo by Josh Nichols (@techpickles)
Josh Nichols retweeted
Most companies didn't go remote — they digitized the office. Same meetings, same interruptions, now on Zoom. Open and Async is out today: the open-source way of working — in the open, in writing, async by default — turned into a playbook for your team. open-and-async.com
1
2
2
460
Josh Nichols retweeted
Situation 1: dev A thinks approach X is correct, dev B thinks Y is the right way. They argue and try to convince each other. Situation 2: dev A thinks approach X is correct, tells the LLM to implement it. There is SO MUCH learning in Situation 1, lost when using LLMs....
185
84
39
1,538
182,658
Stumbled across notes from my first @RenderATL (always keep your notes!). From @kishau : "Don't create glass ceilings for yourself by being an ineffective communicator and not being a good storyteller... If you make a technology choice, be able to talk through the alternatives you didn't pick and why" still true and relevant for my current role I didn't even have then🙏🏾
2
4
37
1,771
"None of our top 50 endpoints by throughput can have more than 5% of responses be >500ms" This is a good perf goal. It scopes to the most important parts of the app, is set based on expectations of human users (users can feel >500ms resp), and it's usually quite achievable.
2
58
3,472
Josh Nichols retweeted
I just released Zeitwerk 2.7. Now, you can define namespaces with manual constant assignments too (think, Namespace = Struct.new). To the best of my knowledge, this completes the most important goal of the gem: to fully match Ruby. 🎉 Let me elaborate a bit on why that was not supported before, and how we have been able to remove that long-standing limitation. First, let's take a step back to understand a tricky aspect of namespaces. Consider this Hotel namespace (in Ruby, both classes and modules can be namespaces): # hotel.rb class Hotel include Pricing end # hotel/pricing.rb module Hotel::Pricing # Pricing related logic extracted to a mixin. end You cannot load any of the two files in regular Ruby, right? To load hotel.rb you need Hotel::Pricing in place, but if you try to load hotel/pricing.rb, you need Hotel! But that works if the project is managed by Zeitwerk, and it worked with the classic autoloader too. To support that use case, the :class event of TracePoint was instrumental, and it was the only technique I could think of in 2018. It worked this way: When TracePoint notifies that Hotel has been created, the loader scans its subdirectories and defines autoloads (issues Module#autoload calls) for child constants, in particular for Hotel::Pricing. The key observation is that happens precisely before the include line is executed. When the interpreter hits that line, the autoload is in place and autoloading hotel/pricing.rb is possible (because Hotel exists!). Problem was, the event was not triggered for manual constant assignments (think Hotel = Class.new). So, while that was a corner case, unfortunately we could not achieve full parity with this technique. The most important and common way to the define namespaces, using the class/module keywords, worked. But argghhhh. But the suffering is over my friends! In part motivated by this problem, @_byroot implemented Module#const_added. That callback is invoked in both situations! 🤘 Thanks to Module#const_added, the limitation has been finally removed. Also, Zeitwerk no longer uses TracePoint internally (/cc @yukihiro_matz). Zeitwerk 2.7 requires Ruby 3.2 or later, and upgrading should be seamless for existing projects. Don't worry if your app uses an older Ruby. Bundler realizes 2.7's Ruby version constraint is not satisfied, and ignores it in that case. Gemfile.lock will always get a version compatible with your app. Same for gems that need to support Ruby versions older than 3.2, a version constraint for zeitwerk like ~> 2.6 will do the job. Client code will automatically use a compatible one. Mission complete! 🎉
8
23
1
185
13,552
Josh Nichols retweeted
We're hiring engineer #4 at @scholarlysoft on-site in Seattle. If that's you, let's chat! DMs are open. scholarly.breezy.hr/p/a8959b…
1
7
2
17
6,025
I have a long list of ideas I want to work on but not enough time. I do have some money though. Is it time for Speedshop's first employee? If you are: 1. A good writer 2. A solid Rubyist that can build a product from start to finish ... maybe it's you?
8
19
2
94
16,524
Our system tests were slow and we couldn't figure out why... turned out it was a 1-line fix! I've written this post for @GustoHQ's engineering blog: engineering.gusto.com/our-ru…
1
10
93
13,311
I'm out here saving humanity, and you're are all "scott." smh
14
21
8
316
29,635
Gusto's @techpickles has shipped Singed, a swiss-army-knife tool for getting flamegraphs anywhere in a Ruby application: github.com/rubyatscale/singe… It slices, it dices, it profiles: * Blocks * Tests * Requests * Controllers * Command line ... all using Speedscope! It's great.
8
62
4,355
9% faster response times observed too 👍
Took us, 3 engineers, about 2.5 months to upgrade from Ruby 2.7 to Ruby 3.1
2
1
35
Josh Nichols retweeted
Took us, 3 engineers, about 2.5 months to upgrade from Ruby 2.7 to Ruby 3.1
16
9
3
174
Don't wonder why "some rando in Nebraska" holds up half the internet and then shame them when they don't put out a bugfix fast enough for your liking. We can't narrow the pool of OSS contributors to only people who can put up with this bullshit.
3
35
Josh Nichols retweeted
If you work in a company with many 100s or 1000s of employees, the best networking strategy actually lies in plain sight within your company. Here’s how it works:
55
191
24
1,934
When I was in my 20s, I wished I only worked for equity (because I was lucky enough to afford it). This industry taught me that everything you "own" as an employee relies on what your managers think, and it can be lost in a single reorg. And it happens again and again.
This Post is from an account that no longer exists. Learn more
5
24
404
I realized this morning why the whole "Elon arguing with Twitter devs and firing them" brouhaha of the last few days has hit me on a physical level. It's because, as a senior IC dev, one of the most important aspects of my job is preventing crap like this. (Long 🧵incoming...)
14
145
25
736
👀 I'm looking to hire mid-senior engineers to come join me at a stealth startup tackling SaaS pricing insights! We're a WOC-founded and led company out of NYC and remote-first. RTs welcomed!
14
122
7
256
I'm looking to plan my workshop schedule for the first half of 2023. If your company would be interested in bringing me in for a Rails performance workshop, in person or remote, let's do it! I've got hundreds of happy former students and would love to add some more.
2
8
3
24
Async communication is a simple concept: you send a message without expecting an immediate response. The surprising thing is the side-effects of async if you make it the default communication. Here are some core learnings we've done at Doist in the last 8 years 🧵
29
138
45
788