yak fashion photography
Streamed
Divider tag PR for ARIA accessibility improvements. Vote hydration PR refactoring with innumerable delegation. Backfill mod data PR for moderator granted_at timestamps. HatsController mod issue filed for splitting out moderator actions. Tags field issue about layout bugs. Rescuing bugs from the failed jobs queue; Telebugs reporting configuration. ActionMailbox UTF-8 encoding and multipart. Doffing mod hats. Refactor story cached columns Malort advent calendar; cat body language.
scratch
topics
PRs
fieldset and legend https://github.com/lobsters/lobsters/pull/1792
high contrast arrows https://github.com/lobsters/lobsters/pull/1780
divider_tag https://github.com/lobsters/lobsters/pull/1806
tag list https://github.com/lobsters/lobsters/pull/1800
vote hydration https://github.com/lobsters/lobsters/pull/1748
backfill mod data https://github.com/lobsters/lobsters/pull/1805
issues
filed HatsController mod https://github.com/lobsters/lobsters/issues/1807
tags field again https://github.com/lobsters/lobsters/issues/1801
failed jobs queue
telebugs reporting from failed jobs
specific missing comment that was reported
file or fix rest of the failed jobs
clang dep for docker https://github.com/lobsters/lobsters/pull/1808
if time: more headline work
actionmailbox exception:
Type TypeError
Message text must be UTF-8 encoded; got ASCII-8BIT!
/home/deploy/lobsters/shared/bundle/ruby/3.4.0/gems/commonmarker-2.5.0-x86_64-linux/lib/commonmarker.rb:21:in 'Commonmarker.parse'
/home/deploy/lobsters/releases/20251117214446/extras/markdowner.rb:39:in 'Markdowner.to_html'
/home/deploy/lobsters/releases/20251117214446/app/models/comment.rb:333:in 'Comment#generated_markeddown_comment'
/home/deploy/lobsters/releases/20251117214446/app/models/comment.rb:275:in 'Comment#comment='
/home/deploy/lobsters/shared/bundle/ruby/3.4.0/gems/activemodel-8.0.3/lib/active_model/attribute_assignment.rb:69:in 'Kernel#public_send'
/home/deploy/lobsters/releases/20251117214446/app/mailboxes/inbox_mailbox.rb:7:in 'InboxMailbox#process'
second actionmailbox error:
Type NoMethodError
Message Can not decode an entire message, try calling #decoded on the various fields and body or parts if it is a multipart message.
/home/deploy/lobsters/shared/bundle/ruby/3.4.0/gems/mail-2.8.1/lib/mail/message.rb:1895:in 'Mail::Message#decoded'
/home/deploy/lobsters/releases/20251023174351/app/mailboxes/inbox_mailbox.rb:22:in 'InboxMailbox#required_info'
/home/deploy/lobsters/shared/bundle/ruby/3.4.0/gems/activesupport-8.0.3/lib/active_support/callbacks.rb:361:in 'block in ActiveSupport::Callbacks::CallTemplate::MethodCall#make_lambda'
send webmentions:
Type ArgumentError
Message wrong number of arguments (given 0, expected 1)
/home/deploy/lobsters/shared/bundle/ruby/3.4.0/gems/activesupport-8.0.3/lib/active_support/core_ext/object/to_query.rb:14:in 'to_query'
/home/deploy/lobsters/releases/20251111162914/extras/sponge.rb:189:in 'Sponge#fetch'
/home/deploy/lobsters/releases/20251111162914/extras/sponge.rb:260:in 'Sponge#fetch'
/home/deploy/lobsters/releases/20251111162914/app/jobs/send_webmention_job.rb:72:in 'SendWebmentionJob#perform'
title
post-stream
fix archive pages
Transcripts are generated with whisperx, so they mistranscribe basically every username and technical term. They're OK but not great, advice appreciated.
Recording
01:38Good morning.
I'm Peter.
bsandro VoHiYo
This is Lobster's Office Hours.
Alright, let's figure out where I'm at.
So, this website is Lobster's.
pushcx Welcome, drop questions in chat anytime!
Hey, Bisandro.
02:02Got my little message up.
Got my timer set.
Alright.
bsandro will you be participating in AoC this year?
So advent of code, probably not.
I don't usually do advent of code.
I don't know.
I think it is a very neat and I've made it a few days in a couple of times, but I've never been so interested as to stick with it.
No particular reason why I really do think it's a lovely event.
Maybe this is the year I should go for it because it's lighter this year.
bsandro yeah, 12 days only
I remember just recently seeing a
bsandro instead of usual 25
announcement from the creator that they're doing fewer puzzles this year because it's an enormous amount of work i assume all right yeah 12 instead of 25 yeah i mean i can barely write a blog post let alone a two-part interesting computer science puzzle that works in any language
So quite a bit of work there.
03:51Figure out where I'm at here. So between streams, when we are not chatting about stuff, I merged a couple of pull requests, which is why there's this note about this person's commits being unreachable. So let's go take a look at the pulls. And let's go take a look at the issues. There we go. Trying to prune my Firefox history so that the top completion is the one that sorts correctly. I'll just fix one of those pet peeves. Yeah, so... These two about the field set and... Oh, I've got Vim open. Man, I am getting a late start today. Key honors. And then we've got a title. Oh, yeah. Well, I already know. Fix archive pages. The last... Two streams are not on the archive, and the two streams prior were pretty badly delayed because my little archiving script broke, and I have to spend some time to fix it. Something in the Twitch API changed. It's just one of those things that's going to happen every year or so.
05:31So these two were both pretty extensively reviewed on stream here.
If you saw the last stream, the only thing to do was some minor cleanup like indentation.
And this contributor also put in a .editor config file, which is kind of a
I don't know how well supported it is but it's supposed to hint editors about this kind of spacing so hopefully it saves other contributors some time and annoyance fingers crossed.
And then.
So let's see the topics.
Username work.
Or no, it's more headline work that I call that branch.
called that branch headline didn't i all right using my dj mark create dash r os so this is actually the headline i already have a headline i'm gonna have to look into that all right so let's create one called headline current and then you know
know you're using version control right when you start naming your branches like headline final v2 dot final and let's remove i think it's rm username is it just r no oh there was a rename okay they call it delete yeah this is one of those style things jj doesn't
graefchen AoC? limesPoggers I think it is a little sad that it is only 12 days. But it is probably for the better IMO. limesLurk
really lean into let's use the unix tradition git does that's been one of the things i've had some friction about moving from git to jj is i expect to see the unix kind of names of rm for deleting files and it's not yeah all right so with that fixed if time or headline work
I already know there's an issue with usernames.
Yeah, you know, it's one of those things like open source software where they're creating something and giving it away free.
Maybe I'm being Midwest about it, but that's called a gift and you don't get to make a lot of demands of people who give gifts.
While I would like more gifts, and I totally understand the desire to have 25 gifts instead of 12, eh, every one of them is a gift.
No complaints.
And especially if it means that the maintainers don't burn out.
Here, let me find something cute.
I just saw this on the shelf the other day.
Speaking of advent calendars...
Because this is a... Light mode warning.
bsandro Chicago as in Windows 95? :P
Because this is such a Chicago-oriented stream, and Lobster's is a Chicago website, Malort, Chicago's... God, what's the right adjective or pejorative here?
Chicago's unique local liquor...
Malort has released an advent calendar this year.
Now in a normal advent calendar, you have 25 little windows and each one is a pleasant surprise.
In Malort, each one of them is a little bottle of Malort.
It's so dumb.
And we aren't yet into the Advent calendar season, so I hope nobody's opening these yet.
I do know they make a couple of varieties, but my understanding of this gift is it is the standard Malort, which is distinctive in flavor, just 25 times in a row.
It's such a dumb joke, I have to laugh at this one.
woosaaahh Hi everyone !
Windows 95.
I just saw somebody putting Windows 95 in a container and running it on like a Raspberry Pi.
That was a weird moment of like, oh, right, that desktop OS that I used is now the kind of thing that you can run on a Tic Tac.
graefchen It was a year long project as far as I know, as Eric Wastl said in this talk: https://youtu.be/uZ8DcbhojOw limesLurk
Howdy, Woosa.
I was around a family member's small kid.
He's got to be, what, eight or nine now?
And he had...
They got him an Apple watch with the cell phone signal because they didn't want him to have a phone.
But I was looking at it and it was like, oh, he has the Dick Tracy watch and more because he could use it to call his buddy that lived three blocks over and set up a play date.
He could use it to call his uncle.
And I don't know, it was just very magical.
I got a big kick out of it.
11:03bsandro on raspberry pi you could run them since forever; I think the newest project brought Win95 alive on ESP32 microcontroller
Oh, Gravechen, thank you for this link.
This one is going in my to watch later.
And I see, well, here at least for me, I don't think I remembered to block Google cookies on this browser.
But there is a second one talking more about it from two years ago.
Yeah, one of the funny things that happens if I block
woosaaahh when you have few secs, could you tell me on lobsters, what greyed news title means please ?
google and youtube cookies which i do in my primary browser very often one of these top five or six is like why the flat earth is real or like weird self-helpy stuff yeah i must not block cookies because i've they've loaded enough stuff that they're like aha you were interested in programming which yes every time i'm in this browser i'm programming stuff
bsandro do you watch other YT/twitch programmers?
if you don't have youtube cookies like in a new incognito windows woosa it means one of two things either it's deleted and you are the submitter so you can see that it was deleted or it's been heavily flagged and so it has a negative score
If you want to talk about a specific story, we can talk about a specific story.
I can't think of one of them in the last day or two that's hit a negative score.
Oh, this one?
The Apache 4, maybe?
It hit zero, which does have a small styling change.
Bissandro, I don't watch Twitch streamers.
It is kind of a running gag that I'm pretty ignorant of Twitch community norms.
pushcx https://www.rubyevents.org/talk…
I do watch a lot of programming videos because I like to play video games, and without distracting into that too much, I often have a...
woosaaahh am a heavy viewer, I don't have an account (yet?) so might be the second case
woosaaahh (flagged)
a programming talk on in the background, or when I'm doing chores like washing the dishes, it's really easy to have an iPad nearby with a programming talk running.
And I watch pretty much every talk that shows up on Ruby events.
You know, there are some I get.
three minutes in and I'm like, boy, I'm really not interested in this or I know everything about this.
I'm going to go ahead and skip to the end or just skip it entirely.
And otherwise, yeah, I watch a lot of programming talks.
I especially will just grab an entire conference at a time.
So I really miss the Strange Loop conferences.
God, they had so many good, weird talks about
fun issues in programming language design, or I hesitate to say ESO langs because esoteric langs are a different thing, but there would always be stuff that was in a language I don't know.
And as you might guess, I read a lot about programming.
So that kind of novelty was always a delight.
That's nice.
14:48I agree with Jared here. Ruby box is probably going to be a big deal.
...57All right.
woosaaahh thx
So coming back to maintenance, these two, and this one is a draft.
Hey, Firefox is actually opening these in the right places now.
Maybe something about closing and reopening.
15:29Woosa, the flag should be pretty obvious if the score, if the number to the left of the headline is zero or negative, or I think even logged out, you will see whether there are flags to the right of the title. Oh yeah, this one is new. So we're going to go easy one first. And I say easy one because I haven't looked at this one, but in one of Federico's other PRs, he improved ARIA accessibility for that, like, when you look at stories and a lot of things, we have like this dividing line, just a vertical pipe character. And we do this all over the place and if you have the aria role or aria attribute hidden true screen readers won't read it which is one syllable distraction gone so this is a a breaking change to core ui for screen readers and i hate breaking changes to core ui but this sure does look like a nice little improvement so Will make a divider 10 so Federico did this in one of his other PRS and I saw it and I was like oh obviously we could have a helper and do that everywhere. And then speaking of gifts he's open to PR to do that everywhere.
17:31I didn't spot... Did he do this?
18:25Did I not merge the PR where he started doing that? Did that start over here maybe? This is the only one of his recent PRs I haven't merged.
...49Yeah. Okay. So I was distracted because I was like, wait, I didn't see in the diff the places where he started to use this. But I hadn't merged this yet. So, okay. Let's grab this link.
19:39It's like a train.
20:30Throw it up there.
...37Did I put that in the notes? Yes. That probably gives merge conflict on this one, but... Yeah. Wait, application CSS. Let's go look at the diff.
21:03i don't see a conflict maybe oh i bet it's because something else was added here between this because i remember in his other pr he was touching stuff around this breakpoint that's not bad all right so this one's gonna have to get updated to say the let's say Was there anything else about this one? Right, this thing about options.
22:14OK, so this one's not ready to go. Even with that little thing, we're still waiting on the options. So grab that. What else do we have? So this one I did a longer review on a couple of times. Hydration. And it's starting to, I don't have a spidey sense, but I have a maintainer sense, and it starts to tingle when pull requests get like six weeks old, because it's very easy for them to wind up abandoned, which I don't want. So this one has had a couple refactorings. And I'm curious to see this last one, because my previous review, I had said, I think I left it implicit, but here on stream, I had like mumbled my thoughts aloud that I didn't like that the hydrator had it to be passed down as an explicit argument to the templates. Because that seems like such a database level concern. Now here, look how much shorter these are getting. All of this repeated work is vanishing into the hydrator.
23:53And the hydrator, yeah, they pulled in innumerable. Aha, look at that. That's working through.
24:16So innumerable has an API and if you support, honestly, I think if it's just, if you support each, you support the interface, but there's some more stuff that is going to get called that you have to delegate down. Theoretically, we could, you know, enumerable actually has a pretty wide API. There's a lot more we could delegate down, but this must be what the template uses. So this, we set up the instance variables. And then we have an each. And then we have a thing to, this is great. There's no extra work. There is a test for this view, so if that was not allowed, it would actually fail out. And I would prefer to have trailing commas. It is one of the few places I disagree with standard RV, but yeah. All right, so everything is addressed. I have to run the workflow. So unless the build fails, I get to merge this down. This looks great. So we'll give this the two or three minutes it takes to run. I wonder if GitHub is backed up. Usually the security test and the linter finish in two seconds, but they're hanging out cute. So maybe they'll need more than a couple of minutes. All right. So this one.
26:33Nice to see a little progress dot. Okay. Yeah, a little bit of an unusual cue there. I'll give that a minute. So this one is part of a running set of bugs where we added the content security policy. Images went missing from I think five, one, two, three, four, five different stories. That's it. We have exactly five stories with images because only moderators are allowed to use images and we just haven't needed them. And then changes made here. yeah common marker we're going to be back into that oh that was the other thing for my to-do list was i mentioned in my stream announcement that there are some errors that have been piling up unnoticed the failed job queue excuse me a sec The failed job queue is not correctly logging to Telebugs or Telebugs is not emailing about them. And I would believe both things could be an issue. So I got to look at those and we'll see how that goes.
28:43Sorry, Twitch is distracting me with silly achievements around, I guess, promoting other streamers. Alright. Alright, so let's take a look. Hosted as moderator. Granted moderator at. Is that a new attribute on user?
29:52Yes, it is.
30:11What's happening here? Update commons. It's re-rendering. Sure, I follow.
...31Except... This... Oh, this already does exist right so that's for re rendering comments where's the initial rendering. Do we actually do that correctly because it's very possible we broke that Okay, yes, so we. call can have images.
31:10How image is false. Here we are saying posted as moderator. OK, so this is using a different rule of can have images, which I don't see touched here. Let me reread this suggestion for comment.
...45Back fills the date when the user became a moderator based on the logs. Sure, on the date of their first There is no demotion feature. So there's a couple of things happening like.
32:30These dates are not accurate and I want to be nitpicky about it.
...41And I want to be nitpicky about it because. I try and be really, really thorough about everything moderation related. And if someone became a moderator on Monday, but only took their first action on Tuesday, I don't like having a date in the database that implies they became a moderator on Tuesday, not Monday. So this has to be even more manual of, I mean, there's only been like nine moderators in the history of the site. So let's just find the nine and fill it.
33:28mist1fy do you know how to scrape a website that uses a websocket?
Yeah, OK.
So this one finished.
Let's go ahead and merge that down.
35:00I'm being a little tongue in cheek here of story lists of stories can start are correct, instead of the usual practice but.
Maybe i'm i'm saying i'm being self deprecating but.
We have had this bug.
graefchen I rememmber more or less manually scraping a website once. limesBlink It was fun using the console for stuff. limesO
Five times, maybe.
Every time we add a new list of stories this happens basically.
mystify to scrape a website that uses a web socket are you asking as a developer or you're looking for a tool i guess i already know the answer of if you're looking for a tool i'm not aware of any tool that does that
Because it would be such a site-specific thing, WebSocket can just kind of dump data back and forth and API stuff back and forth.
You'd have to customize.
36:12And then I guess I also know the answer of, as a programmer,
mist1fy was trying to build it myself, issue im running into is the websocket api accepts my connection then folllows it up with a close packet :(
I've never tried to do that, and so I don't, off the top of my head, know a good toolchain for it.
Yeah, I don't know.
That sounds pretty painful.
mist1fy fair enough thanks anyway tho broski
How fast does it follow it up with a close packet?
One millisecond?
A thousand milliseconds?
mist1fy uhhh like 600-700ms
Good luck with your scraping.
If you do get that working, I would love to see that blog post.
Please do write it up and submit it to Lobsters.
Okay, so 600 to 700.
Sounds like you're missing a keep alive or a handshake of some kind.
So if you look at your...
network tab in your web developer tools.
You can probably reverse engineer what that is.
But it's going to be a very site specific custom, even if they don't call it a protocol, it's going to be an ad hoc protocol.
Six to 700 milliseconds really sounds like a timeout where it's the server is expecting the client to say something useful.
mist1fy ya thats what ive been trying but its weird because the second handshake doesnt seem to have anything attached
Although I would be a little more certain in that answer if it was exactly 500 milliseconds or like 503 milliseconds, because then, you know, that's a very human round number.
38:09Second handshake.
Huh.
Can I ask what site you're trying to scrape?
if it's something you don't mind sharing.
I'm kind of curious about that.
Chagai95 Can I get an invite?
mist1fy its a online sportsbook that uses a websocket for odds
And actually, yeah, it must be something that's very single-page app shaped.
pushcx https://lobste.rs/chat
I would really hope to.
Changi, yeah, here's a link to that info.
An online sportsbook that uses a WebSocket for odds.
Ah.
mist1fy lemme drop a follow, ill come back in a couple of days if i figure it out :)
Is it an app then?
Well, I guess not.
Yeah, because I was going to say, I would be tempted to back off and say, surely there's a URL, because if it's a single page app and it's getting you data, but I imagine with an online sports book, there's one view of, I don't know, current things you can gamble on, and then it's fetching a list of all of them.
Sure.
Those things wouldn't have individual URLs.
Interesting puzzle.
It's not an advent of code like we were talking about before, but interesting programming problem in a practical sense rather than a CS sense.
40:23mist1fy its really weird, I have some sites where i have found apis that i can use event ids on, but this one specifically uses a websocket
Let's look at the schema.
Yeah.
...42Do we have? Yeah, we have the mod log use.
41:20mist1fy anyway enjoy ur evening bro ill be back at some point SUBprise
Which... Actually, I'm not sure if we... Yeah, doffed five years ago.
It's morning for me, but thanks.
Have a good one.
Doffed eight years ago.
Hats are automatically doffed when you depart.
I must have set those manually, right?
42:22I don't see any code that says doff that. That's not correct. This line. So there's a manual method for doffing your hat.
...532018 01 this is one of the earlier things i did on the site so this is six no this is three or so months into me being the admin of the site i added dofdat because jcs's hat still listed him as a sysop and i wanted to not delete it all off all his old comments or anything
43:27This. Revoked. This is a little bit dangerous, because if we destroy the hat, we're going to lose its use on any previous comments. I think that's happened. Revoked.
44:33or not recent action.
...43What is this? Provoked hat user developer. It's happened exactly once. Was that hat ever used? So we can figure that out. Well, I don't have 500s about it, so it was probably never used.
45:29Well, there's not going to be a, all right, what do I want?
MorningScifi I don't know any ruby but the single line of code "destroy!" is quite funny
Romance short ID from romance left outer join hats on hat ID equals hats.id where hats.id is null.
Morning sci-fi, yes.
The fact that you can
put an exclamation point, and an identifier makes for some of those cute things.
So what's happening there is most languages, you know, you can use letters, numbers, underscores in method names.
In Ruby, the final character can be an exclamation point or a question mark.
An exclamation point mostly gets used for...
It's very...
There's no strict rule about it.
And so mostly you see it in Rails for things that take destructive action or have surprising side effects.
That's, I can't have done that right.
Hold on, there are not that many comments.
That's every, oh, right.
And where had, I hate that it's not composable.
That was finding me every okay, so there are no comments with hats that have been deleted.
MorningScifi I did a quick github search for it and found only a few thousand files with that exact line, so I figured it was more unique to your codebase
So that's at least one bug avoided.
Now I'm just going to delete this.
47:16It's destroy is not unique to our code base.
So there is a
MorningScifi aha
database library in Ruby on Rails called active record and destroy bang is one of its methods.
In a lot of web apps, we tend to do soft deletes where instead of deleting a record, we put in a deleted at timestamp or use one of a couple other methods rather than delete the record.
Because like you just saw me checking for in the prod console, if someone had used that hat on a comment,
Then the foreign key is just hanging out pointing to a non-existent record and the site throws 500s or we have even more nil checks so.
I got to alias that.
48:51So with that foot gun, what did I do? There we go. With that foot gun removed, what did I come in here for? Dolphin. Yes. Delete. So when a user is deleted, should all other hats be doffed? Certainly their moderation hats should be doffed. There are others. So we just saw a hat that said Apple developer, and odds are that they ran afoul of the Apple PR department. I don't know that person, but Apple is very tight lipped about who speaks officially on behalf of the company, where a lot of places are very happy to have a developer who does a little bit of like outreach. Apple is not a company that comes to mind for that. So, yeah.
50:02pushcx https://lobste.rs/hats
just go ahead and say so if if we look at the existing hats and i'll throw this link in the chat a lot of it is about being involved with a project or being an employee somewhere and
...43If someone deactivates their account, which is a thing that they can do, I think I would rather doff their hats and re-approve them than assume months or years later that they're still involved. I don't know. So I don't have an intuition for How often people come back and they're still involved in these projects and I guess every time it says like core team member or developer. These people probably are yeah let's just take off moderation hats.
51:54Find each. That's a little bit funny because someone is not going to have 1,000 hats, especially 1,000 moderation hats, but it's a good habit to use.
52:15Do we need doff by user with reason? No. Because if they deactivate their account, that already creates a mod log entry. If they're banned, that creates a mod log entry. We can just... Yeah, we'll just kind of slot this in. We'll have to add equals to the current. Actually, in which case, let's just say updateAll . Let the database do the work. All right, that method is updateAll. Yeah, and it takes a hash. And it's a little dangerous, but we're doing a dangerous thing.
53:30And then there is, in the hats controller, the dof method. And I think this is one of those places where the moderator, yeah, dof by user.
54:00Only hat user or moderator can doff. That's great. And then only the moderator can update in place. Let's file an issue about that. So I've been slowly moving moderator tasks off into their own controllers. This would be a nice one for someone to contribute.
56:09Can do things to their own content. Let's hit max delete minutes.
...34Max edit minutes. Deletable days. I'm never going to type that correctly.
58:30the, what's the, I kind of want to say the stack trace, but when following
59:04along its route.
...20None of the code should happen in this moderator check.
...37That's...
01:00:44This feels like one of those where I spend as much time writing it up as I would spend GitHub. GitHub, how do I? GitHub, I can't scroll down to find good first issue. What a great single page app you have, GitHub. This floating window thing. I don't know, maybe it's a year old now, maybe two, but I'm not warming up to it. Because I keep running into issues like that.
01:02:14Just the other part of this. Yes.
...28This call to two HTML.
01:03:13Where did I see that? Oh yeah, story can have images. There's a
01:04:08Something like that.
01:05:50All right, fill moderator data.
01:06:01Cool. So that's all the pull requests looked at real quick, because I already merged those two before the stream. Yes.
...20No movement on that one. All right. So there's the issue I just filed. This has gotten, since I looked, just past an hour. So I will do my, one sec.
...51pushcx This is Lobsters office hours, ask questions in chat anytime!
Okay.
...59Do my little bumper that this is Lobster's office hours, and folks can ask questions anytime. So this one, an app mention didn't get linked. That's almost certainly going to be my bug. We can re-render those comments and fix them. Actually, re-rendering that comment would probably fix it, but yeah. Speaking of splits, that's another one of those. Yeah, so I saw that already. So this one, this is an old bug that's come back. And if it's not back, it's something with the exact same issue as we had before.
01:08:00huh and last time the issue was that the this box was getting to be like one pixel wider and then it kind of fell down a little in it so it rendered over the label this just sounds like it's missing position absolute Where do we do absolute? Mine's 1648. Hmm. Yeah, I do not remember the history of that one. How did I do that? Layout fixes. Yeah, this is me trying to fix the bug the last time this came up. So just over three years ago.
01:10:08says tags good all right hopefully somebody will sort that out you have a couple of people a couple of regular contributors now who are really interested in front end stuff so fingers crossed all right so that's that's kind of making the rounds
...41Let's grab some of these links and the tags field.
01:11:01Okay, so that's all of the activity. Did I close anything between streams that's worth talking about? No, that's... The one fixed by the re-reading this issue. Okay.
...35Then that was the same thing. This one. Yes, I fixed. All right. Cool. So the next thing on my to-do list was related to jobs.
...54So I'm pulling up the job control panel and we have a couple of layers of this here. So there's, what do we have? We have failed jobs. in general, we have the specific missing comment that was reported. We have failed jobs in general, and we have century, well, rest of the failed jobs reporting or emailing. So someone reported to me that they sent a comment in mailing list mode and it didn't appear on the site after, you know, a minute or two. And I think by the time they reported it, it had been a couple of hours, which the longest really that posting a comment should take is like 90 seconds. And that's assuming the sender's email infrastructure is kind of backed up.
01:13:20And I thought, well, that's weird. And I didn't get an exception email about it. And I thought in Telebugs that I had reconfigured the emails to send. So I'm looking at exceptions in the last seven days. And it is not present.
...58So it's not that emailing didn't happen. It's that job queue is not correctly wired up to send Sentry emails. And I say Sentry, but Telebug's reporting from failed jobs. So I've got to figure that out.
01:14:27And then there's 53 failed jobs. And it looks like just kind of skimming off screen here that three or four of them are the same. There are really only like five unique exceptions.
01:15:05So either I will file issues or I will fix them. So let's, first let's fix infrastructure.
...29So how, let's check the telebugs docs. Maybe they have something about jobs here. I love when docs have a, everything on one page so I can just control F for. Okay. So it's, oh, it's using solid queue. I don't want to split them out. Hmm.
01:16:28And that's the only mention of solid keyword jobs. So installing Telebugs should probably have automatically set that up. For some reason, it's not. So that's...
...54Yeah, we install the Sentry SDK. And there's this DSN thing. Where is that set? Maybe I did something wrong. Config, initializers, telebugs. so maybe when this comes up as the job server it doesn't have this credential that's possible that could be a misconfig on hatchbox all right i'm gonna Let's see, where's my little message? Let's step away for two seconds here for a quick bio break. I'll be right back.
01:21:56Okay, let's turn that off. There we go. So, best guess was that these credentials are not present, or it's possible that this initializer doesn't even run.
01:22:22How would I figure this out? What I would really like, yeah, let's check.
...50Anybody talking about this?
01:23:18This has nothing to do with Solid Q. GitHub.
...48And on Action Mailer. All right, so this is the exact problem I have, except these exceptions are not showing up.
01:24:22Are they all ActionMailers that aren't showing up? Yes. OK. So it's weird to look at the solid queue. I guess ActionMailer is built on solid queue? All right. So this is the exact code I want. This is why this exception got lost.
01:25:13Yeah, I'm a little surprised that The Sentry doesn't automatically hook into that.
...52And I keep alternating between saying Telebugs and Sentry, because Sentry is the error reporting API, and then Telebugs just copied its server side API to receive.
01:26:16Yeah, I don't see anybody talking about this. I guess that's it. Let's kind of grab that. And I think what's happening with the other failures that are in the failed job queue is Telebugs had email disabled for a while, because we had an error that was causing lots of exception emails a while ago, and I turned it off, and then it's easy to not remember to turn things back on.
01:27:27Why did it... Why did split not give me the jujitsu interface to actually split out my... Something's wrong there. Oh my god. Split dash i? Ah, it expected me to name files. And since I didn't, it started in some odd mode. What is this doing?
01:28:22Something is wrong there.
...29How do you keep making a new commit when I abandon the garbage I'm on? It's a weird fucking behavior. Look, I want to back up one. I swear that's also a change.
...51JgAbandon gives you a new change while JgRestore was restore. Yeah, all right.
01:29:12OK. So this one is the one I want to split out.
01:30:15So I have all these.
...52so that that'll take 30 seconds and then that's probably fixed i won't know until there's another bug so i'm gonna have to just keep an eye on this mail queue let's look at that specific missing comment
01:31:29Apparently Cloudflare is having another outage. So if that got you, what, day before yesterday, do it again.
01:32:02And I am peeking off stream at my email and. there's activity.
...24Possible causes something about common marker.
...42Exodise. Shouldn't need to. Crossref. 270. Precompiled.
01:33:08I think, is he saying you shouldn't have to? yeah the build tool doesn't handle ruby 3 3. okay so this could be where this aha that's why
...42We're probably just seeing somebody bumped this from 3.3 to 3.4 as their upper limit.
01:34:10So if we go look at this.
...26Really? A backslash? Your commit message is a backslash? I mean, you... Sure.
...44Yeah, I don't see anything about bumping Ruby version, but that's...
...56Probably this again.
01:35:33Really? Why can I not? Her pull request is right here, right?
01:36:27What was the other? And there was something else.
01:37:06I wonder if this is just gonna be a recurring issue because we follow Ruby versions pretty closely.
01:38:28Let's throw this in here.
...57all right so this side of this is fixed so let's go find the specific error the specific error was that a routing job failed from action mailbox and I'm gonna just grab the end of this. The exception looked like this.
01:39:45We recently bumped Common Marker, and it has a new lower level dependency. because they literally swapped out their rendering engine.
01:40:04So the email that came in must have parsed a little differently or had an odd heading. And I'm looking at the failure in mission control, and it doesn't actually show me the email. But I guess I don't need to know the email.
...41Yeah, so let me. It is a type error that the text must be UTF-8 encoded. And it got ASCII 8-bit. What an old school kind of error to get. Been a while since I've seen a Unicode error. So I guess let's look at this exception and figure out the highest point we can intervene to deal with it.
01:41:13You know, there was more to this traceback. There must be more. Yeah. So there's a bunch of layers of active model and stuff that I'm skipping because that's not useful. But mailbox process.
...41And that's the last thing. That's the only other line that mentions our releases directory. I just control F for it. Yeah, this mail decoded is doing the wrong thing. I know we have some kind of helper around UTF. forcibly convert to UTF-8. Yeah, and I see the email parser didn't get included here.
01:42:44Is this email parser still used?
...52No, it is not, because this parse inbound mail is the thing that was replaced.
01:43:04Right. Yeah, nothing refers to that. So this was this is dead code should be entirely dead code now. Yeah. Which means this email parser is dead.
...46see this moved over here so what's what's the outermost layer of this sending user okay so required info
01:44:22I don't think I can assign to the mail.
01:45:24We lost this method.
...53What do we call this? Maybe like tidy?
01:46:05Why are you out of order?
01:47:07Yeah, so this still allows people to do inline quoting and top and bottom. Wait, hang on. I never remember. And top quoting, which is the old school style, but not top posting.
...26All right, where did that go? OK, so we have a call to tidy. Let's see if this wants to run.
...40Do we actually have any tests of the inbox?
...49We have a file. Okay, it's got a couple. So I can add one about this, at least the signature and the quote stuff.
01:48:59I don't actually care that it's a reply. But I do want to prove this variable name as long as I'm here.
01:49:44Now let's grab. Now, why does that have to call update cached columns on story?
01:50:09Because comment should already be doing that.
...21Delete. Or delete by moderator. Unassign votes. Undelete.
...56And is this not happening whenever a comment is posted?
01:51:56This really feels like it should be here.
01:52:18And this goes away. Well, user refresh counts.
...43let's let's figure out where to stick this in these are not in order
01:53:14What is unassigned vote supposed to do? Man, we are plumbing some things. This is sprawling.
...26After destroy, we unassign votes. No, we should not be doing that.
...40And then... So if we call that, this goes away. And this goes in our new method.
01:54:30Now let's see if like half the test suite fails because I touched something that's in a callback.
...44Yeah, I'm almost more suspicious if the test is green.
01:55:15So now I can delete that.
...31It should still be green. Yes. And let's check that that's correct. So if I comment this out, I should see the test go red. Although I didn't see it go red before I added this.
...55Oh, that was the . This is the one that should fail. That other one would have succeeded by a side effect. So let's go back to that. Now I should get a red dot. I just really like seeing tests fail. Otherwise, good. Otherwise, I don't know that I exactly understood what I was changing. All right, so we make a user. We don't need a separate variable for this. We don't need a separate variable for this because we don't reuse it.
01:56:54Let's inline these here. Yeah.
01:57:13And then we process the mail. We do not need to expect it to have been delivered. We're just going to say comment equals last. Expect comment.body to not include quoted in here. 20.
01:58:33define method body. Oh, it's comment.comment. Did I leave that uncommented? No.
...49So that's a legit bug.
01:59:07Probably there isn't a trailing new line.
...30Man, nothing works.
02:00:15Okay, so it is actually calling this method.
...44The wrong thing is coming out. So by default, Ruby does multiline regex.
02:01:23I remember the whitespace behavior on that dock spring. I expected at least one of these to get stripped off.
02:02:01oh, it's the space, right? My test data's wrong. There's supposed to be a space at the end of those.
...30chamlis_ is it the indent in the herestring?
Is it the indent?
No, it's... Oh, am I doing... Did I do dash instead of tilde?
Because it's tilde that strips the leading whitespace, isn't it?
There we go.
Thank you, Chamlus.
Good catch.
I knew I was missing something obvious.
All right, so we can get rid of those debugging statements.
And then what was up with...
the test that I got passing again failing.
02:03:11So process the mail. The mail was delivered.
...27Do you see an updating caches right in front of the F? All right, channels, here's another one for you to see over my shoulder of. Why did this? Silently fail. So.
...57If I put it back, the test succeeds.
02:04:11Is it E or N? I never remember. P. All right, so just the one.
...28So it is actually getting called, but when it's called from there, it fails. Story didn't get reloaded. Let's look at the old object.
...50It helps if I save the code when I delete my raises. There we go. OK.
02:05:02Okay, so now we've fixed a bunch of stuff. Let's look at this.
...17Email encoding errors. All right, good, good, good.
...50I also, here we go.
02:06:27Okay.
02:07:14Go grab that commit and send it to the user who reported.
...45So I'm also going to double check that the user who posted this did.
02:08:05Yes.
...21right yeah the user looks like they did submit this comment manually so i'm going to hit discard on the job so now there are only 53 jobs in the dead job queue which is better but that's a lot it's still only a couple of types so where am i on time i usually stream for about three hours And we are at about two hours, 10, two hours, five. Yeah.
02:09:17There is it. Different error in mailing list mode in the queue. Let's take a look at that. So the next thing on my to-do list was file or fix the rest of the gems.
...41Can I just grab this trace back? Here we go.
02:10:00Make these a quote for the . This feels like code I just deleted. So it was failing on line 22 required info. That's going to be this. Did email parser say something about that? I feel like it did.
...49Yes, if the email is multi-part. So I thought this was getting handled by Action Mailbox. Apparently not.
02:11:18Yes, Google, show results with the thing I'm searching for.
...39Body, body. Who makes these APIs? Body, body attachables. Why are there two bodies?
02:12:30Let's try just this error message. This error message is a little painful because it's like, yeah, you wanted me to decode the email. Why don't you just dig around inside the email and figure out what's wrong with it? This is, I would like a higher level. API here that's just figure out what the body is and give me the body.
02:13:34Okay, so when it is multi-part, then it just goes, YOLO, you're on your own.
02:14:11Is there a non-multipart convert to multipart?
...59Let's grab seal.
02:15:06Multi part. OK, so there is not a function named with the inverse. Which I guess would be single part, but.
...26Especially if that's an attribute.
...36Point action view form builder.
...51Where's the mailbox?
02:16:06It's action mailbox message, not in my documentation.
...46Is it like action underscore mailbox?
02:17:02It's an action mailbox. Let's go down.
...17And where's your OK. Where's your source? Here.
02:18:19Is there a way to search? Yeah. Search in this directory. Come here. Message. Okay, so you have a message class. Multi-part. But you are clearly pulling in from something else. What does message inherit from or delegate to?
02:19:21This doesn't count as yak shaving because I'm not actually trying to do anything. This is more like yak fashion photography where I'm going like four levels deep just trying to find what the API is. All I want to do is look at it.
02:20:39OK, so that's an interesting bug. Oh, because the story test data doesn't exist, let's just create a user.
02:21:24All right, buddy, where are you?
02:22:04I don't see anything about being single part on this.
...38Yep, there is definitely not any kind of single part.
02:23:13And then what I really want to do is retrieve the logic from email parser, the one I just deleted.
And what are the odds that this is the same class?
yuji0908 Hi , how are you doing?
Can I call that parts?
...50Yes.
...58What else can I call?
02:24:09Let's see if email parts art.
02:25:10Actually, middle blank is... Okay.
02:26:02I just want to get this in BIM instead of dicking around two windows.
...38What's the difference between male.decoded and male.body?
...53Not clear.
02:27:10I'm reversing these orders because I'm starting from the simplest email and working my way up.
...35Is standard rp going to change this out for me?
...47I am not including the I because, yeah, that's standard already doing that. I'm not including the I because, like, if you are capitalizing things in your mime type, you can go straight to hell.
02:28:21And then here. Yeah, I'm not doing any of this possible charset stuff because we never used it and nobody's ever complained.
...55So that's my email. From here, it's mail. OK. The boss is around, but he wants to be on my lap because it's cool today.
02:29:20So this can just fall through a never set body. Stuff that works by side effect.
...36Where's the bounce?
...49Let's go look at that bounce description here.
...59No description. of bouncing. Cool. Let's check zeal again. I know writing docs is a lot of work, but how does this stuff get merged without docs?
02:30:30Sir, you've got to settle down. You're not helping.
02:31:29This thing here is finding a body.
...37Want to see a dead body? It's me after writing email parsing code.
...47Hey, Yuji. Welcome. I am doing frustrated.
02:32:22instead of dig we will schlep through multi-part because we are actually doing a couple iterations and we don't know where we're digging all right all right so that is probably all of those routing jobs fixed. Some of them are months old. So rather than post months old comments, I am just going to discard those background jobs. So that gets the queue down to 39 failed jobs. I saw one that was repeated, something about web mentions. How am I doing on time? 20 minutes? Yeah, I can probably do one more if it's straightforward.
02:33:54Let's find that bug. So this is a bug in send web mention job, which means this is failing for every dang job. And we have not been sending web mentions for a while.
02:34:32It was a little obnoxious that all of these are type errors.
...55All right, so something in sponge. Yeah, I'm on a new commit. What line's failing? 189? Fields to query, given 0, expected 1. What is to query? What even is the object here? A net HTTP? All right. Let's close some tabs, right?
02:35:56Where did that fields come from? It is some kind of method. All right. Some kind of object. Wait, it's an input to the method? What the heck is to query? Oh, baby. So it's something on hash.
02:36:35So if I set A1 to query, I get A equals 1.
...46But here, what's happening? Is it like hash within different access or something?
...59Who's calling sponge? Send winbench at job. 172. Wrong side. It is passing a nil for the fields. Well, there's your button. Problem right there. No, we don't want an empty hash. Let's see what that becomes.
02:38:03Cat, you are making it very hard to type. He has started doing this thing where instead of sitting on my lap, he puts his butt on my lap and then he puts his whole front half up on my wrist and drags my wrist down. And he is not a small boy, so that's a lot of weight. All right, goodbye, sir. He got offended that I moved.
02:39:07Is it even going in here?
graefchen Our cats are about 4kg and that gets really heavy over some minutes. limesD They do get heavy after a while.
Because here we're explicitly calling fetch.
Fetch should be a get, right?
Oh, no, because it could be a four kilogram.
I've got to turn that into American.
Yeah, so he's... Let's flip this.
i want to say he's about 12 now yeah so this big boy is 5.4 kilo and that is not fat he has been on a very deliberate vet ordered diet to be exactly the weight he is he's just a big
I don't know if there's a little Maine Coon in him.
He's not fuzzy like that.
But he's a big bruiser, and he thinks he's boss of the house because of it.
Yeah, so if this is saying get, what are we doing in here?
If there's a get with raw post data, which
This might be positional arguments.
Get nil nil.
This is not the commit where I'm going to wait.
So get nil nil.
02:40:48We shouldn't be in here for this exception.
I don't like like I'm confident that this.
graefchen Ours are also fairly small. One is kind of big, but that is purely muscle and she fast (and weirdly agile with a missing tail) limesLurk
fix will get rid of this error but i don't know if i want to and also shouldn't a web mention have a body 172. it's odd to me that the web mention spec is a get rather than a post
02:41:38Agile with the missing tail. I don't know how you could read the cat's mood without a tail, because they do so much of their expressiveness in how they hold the tail. I mean, there is some on the face. You can tell when they're paying attention or when they're scared, but... You know, there's the yes-no tail, the curious tail, the excited tail. Some of that doesn't show up on the face. Oh, the comfy tail where they wrap the tail around you?
02:42:25All right, I'm going to... I don't love this, but I'm going to just do it. Let's check the... Because fields being nil... Uninitialized constant email parser. Did I? Oh, that should have been in the previous commit.
02:43:03graefchen Mainly how she moves and what she does. limesLUL Also at times the ears. I do not know how, but it works. Small little smelly smart buggars they are. limesGiggle
Why did you try and load a file if it doesn't exist?
...17I must have mis-pasted, or I had a line number on it. I had a trailing dot. OK. But now I don't know the commit.
...50And let's back up. And this one, yeah. Let's double check that nobody is calling if fields or fields.nil.
02:44:27Did I actually see the exception? Can I call? Okay, there's the exact exception. Good.
...41So let's kick that up. Yeah, I'm going to throw up the last call banner here because we're coming up on the end. So I want to deploy this and retry. one of these jobs in prod and i guess i'm saying i am confident enough that it's going to pass that i can turn the banner on you can't see it but i'm going through the web mentions and i'm throwing the one away the ones that are older than about a week because it's weird to web mention about something that happened weeks ago
02:45:55That's the. list. one of these to retry retry job with id and then there's a unicode is the new job also that uuid or did it get a new uuid Got the same UUID and it failed for the same reason 20 seconds ago. Did the deploy not balance the job queue? Should've.
02:47:20It's most disappointing. Touch that, root deploy.
...36Let's go look at prod.
...52Active as of two and a half minutes ago. That sure sounds like it recycled.
02:48:15Retry off screen. And there's that exception. This function is explicitly passing a nil. It's not
...55Let's check any instance of facts. So by explicitly passing a nil instead of implicitly passing a nil, it is ignoring my default. Because Ruby in method calls has two nils. So the Mastodon app uses it. I'm tempted to just say, leave it until those things start failing.
02:49:41Yeah. See, here's another instance.
02:50:07Why is this not?
...48Why is this commit empty? Try that again.
02:51:12Figured the service should get restarted properly on deploy. So that one was puzzling. Obviously just recycled. How am I getting an exception? Come on. How am I getting the same exception? Oh, I am sad and mad.
02:52:43Editing the wrong thing because we have two fetch calls. What was the line of code in there? 72. I am not editing the wrong thing.
02:53:52So I'm going to... Something very confusing is happening here because I shouldn't be into this section of the if because this one's a get. I'm missing something obvious here. 72 to 260 to 189. There's another fetch happening. There's a redirect. So that's what's happening. It's trying to send the web mention. And then in the redirect, it's calling itself with a nil.
02:55:00If it's doing a get, we should probably pass through the same thing we already had.
...20And I say that rather than use fields, I'm using empty brace because When you do a get, there shouldn't be a post data. And then it's not matching its own API, is it? This should be a symbol.
...44Does it call to us somewhere? And that's why it's in this block, because it's method. No, it never calls two symbols. So these calls are wrong. God, who's calling post? Because they've been doing gets for ages.
02:56:17Let's get off prom.
...24Nobody calls dot post.
...34So this was one type error hiding in another, hiding in another old API. Yeah, you are. Oh, I'm calling fetch, but this is,
02:57:16Those are fine. They're not hitting this API.
...58So now that I'm on the third fix, can I write a test? I would have to mock out the network with a redirect. I don't want to do that. I'm ready to be done.
02:58:22Kick that out live.
...33Why can I not SSH? Why did you stall? Deploying is not a processor intensive task. All right, are we down? Did we literally crash in the last five minutes of the screen? Website's not loading. Oh, there we go. That was weird and disconcerting. Yeah, the system load is lower than the number of processors. Maybe my network is just being bad. I've got some lag on my typing.
02:59:14We don't use Cloudflare. All right, so the service cycled. So if I click retry on this job. Oh, look at that, enqueued, performed. Hey, it's like a job, but it passes. All right. So I'm going to click retry on the rest of these and they're going to succeed. So we have been sending web mentions. It's just, if the server redirected, we were misplacing those. All right. So I'm going to keep doing those off stream, but I'm done and yeah great that's figuring out how to read cat body language is one of my favorite things too it's it's a fun puzzle and every cat is weird in its own way on that note i will see you all next stream which will be monday 2 pm chicago time take care