1
00:00:00,000 --> 00:00:03,360
I could start us by asking how many times the Package Index has crashed this week.

2
00:00:03,360 --> 00:00:06,960
Oh, it's never crashed though. That's the problem.

3
00:00:06,960 --> 00:00:12,000
Well, this is your answer. This is the show.

4
00:00:12,000 --> 00:00:19,680
Well, here we are. It didn't actually crash. It did not crash. The problem was it should

5
00:00:19,680 --> 00:00:24,400
have crashed. That would have been actually easier. The problem is it hung.

6
00:00:26,080 --> 00:00:32,720
So yeah, we've been having an extremely long-standing problem with the Package Index that

7
00:00:32,720 --> 00:00:41,360
Sven has been incredibly diligent in constantly restarting the servers every time they go down.

8
00:00:41,360 --> 00:00:43,760
But as you say, it's a hang, not a crash.

9
00:00:43,760 --> 00:00:49,280
Yes, and that wasn't even clear. So initially, I thought it was perhaps related to a crash,

10
00:00:49,280 --> 00:00:57,760
because there were some stack traces, well, not stack traces, but dumps, segfaults, or signal

11
00:00:57,760 --> 00:01:03,760
11s in the logs. And it was really unclear what the cause for the hang was. So the only symptom

12
00:01:03,760 --> 00:01:07,760
we had, like the service wasn't working anymore, and this wasn't the website, this was one of our

13
00:01:07,760 --> 00:01:15,200
batch jobs. So it's not terrible for the site. It just means that our updates sort of start

14
00:01:15,200 --> 00:01:20,240
lagging because one part isn't running anymore. And it wasn't really, so the only symptom was in

15
00:01:20,240 --> 00:01:25,840
the logs, there was just a final message, you know, this is sort of, that's the last thing the

16
00:01:25,840 --> 00:01:31,520
thing did, and then nothing else. And it was unclear what's going on. There was CPU being

17
00:01:31,520 --> 00:01:37,520
used, so something was churning, but nothing happening. And this started happening when we

18
00:01:37,520 --> 00:01:45,600
converted over from Event Loop Futures to async/await. So I think we started this almost two years

19
00:01:45,600 --> 00:01:53,840
ago, I think in winter 21, 22, is when we first started this, right? That's when async/await came

20
00:01:53,840 --> 00:02:03,920
out in 5.7, right? 5.6? I think it was 5.6. Might have been 5.6. Yeah, it's two versions per year.

21
00:02:03,920 --> 00:02:10,960
I may be wrong there. Yeah. And initially it was fairly infrequent. And I think,

22
00:02:10,960 --> 00:02:16,240
if, you know, in hindsight, I think it happened more and more frequently because we

23
00:02:16,240 --> 00:02:23,040
converted more and more stuff to async/await. But that's really a guess because we don't

24
00:02:23,040 --> 00:02:31,680
really know yet. We just have a fix now, finally. And like huge thanks in particular to Gwynn Raskind

25
00:02:31,680 --> 00:02:36,480
here because she was really, really helpful in tracking this down. And effectively, essentially,

26
00:02:36,480 --> 00:02:45,600
the fix was to remove one of our task groups, async/await task groups that we'll be using to

27
00:02:45,600 --> 00:02:52,960
kick off our processing. Part of the processing we were doing there was running shell jobs that

28
00:02:52,960 --> 00:02:58,960
do Git operations. And very early on, she suspected that's the problem, but we sort of,

29
00:02:58,960 --> 00:03:03,920
we always wanted to actually find out what the problem was. So we delayed making that change

30
00:03:03,920 --> 00:03:09,600
also because we were sort of hesitant to make it because, you know, when you, because the fix was

31
00:03:09,600 --> 00:03:16,400
actually take out that task group and make those batches not run concurrently anymore. So there was

32
00:03:16,400 --> 00:03:23,520
a bit of a concern that we lose performance. You know, we were running things in parallel.

33
00:03:24,800 --> 00:03:30,640
That gave us some advantage because often things were waiting on network while others were running

34
00:03:30,640 --> 00:03:38,640
Git jobs and doing database updates. So there was sort of a good use for concurrency because

35
00:03:38,640 --> 00:03:43,280
different parts of the system are used separately. And you know, do you want to use, utilize all of

36
00:03:43,280 --> 00:03:52,800
it as much as you can and making that just single threaded was sort of a concern. But in the end,

37
00:03:52,800 --> 00:03:59,520
we probably lost way more time when this job was down and waiting for me to notice or, you know,

38
00:03:59,520 --> 00:04:05,680
respond to the alerts that we had and restarted. And, you know, it's one of those things also,

39
00:04:05,680 --> 00:04:09,920
it didn't happen immediately. So any change we made, we sort of thought, well, is that it? And

40
00:04:09,920 --> 00:04:15,200
then we waited for hours, sometimes days, because you could never know, you know, typically what

41
00:04:15,200 --> 00:04:18,960
happened a couple of times a week. In the end, it happened multiple times a day. That was actually

42
00:04:20,320 --> 00:04:24,480
an improvement in the sense that we had a faster turnaround in trying to debug it.

43
00:04:24,480 --> 00:04:30,480
Because initially, any change we'd made would effectively, you know, let's meet again next

44
00:04:30,480 --> 00:04:38,400
week and see how we did. These bugs that don't occur regularly are a real pain because you do,

45
00:04:38,400 --> 00:04:41,760
you just you try something, you don't really know whether it's going to work or not. And then

46
00:04:41,760 --> 00:04:47,760
you have to wait 24 to 48 hours for it to get the news. And for the first, you know, for the first

47
00:04:47,760 --> 00:04:51,520
12 hours, you might be filled with hope. Yeah, exactly. You think, all right, we've done a couple

48
00:04:51,520 --> 00:04:55,040
of times where it takes us a little bit. It's looking good. It's looking good. And then on now.

49
00:04:55,040 --> 00:05:03,920
But it really was it towards the end, it was happening multiple times a day, which, which is

50
00:05:03,920 --> 00:05:09,600
not a great situation, because it did, like you say, it didn't affect the uptime of the website,

51
00:05:09,600 --> 00:05:16,240
but it did affect our processing of new package versions and that kind of stuff. So it was,

52
00:05:16,240 --> 00:05:22,240
it was, it was not critical in that people could still, people could still access the website. But

53
00:05:22,240 --> 00:05:27,440
it was, it was an important bug. And it's just been, I mean, it must be, well, it's like you say,

54
00:05:27,440 --> 00:05:31,600
it's since the introduction of async/await, which is a couple of years, isn't it? So yeah,

55
00:05:31,600 --> 00:05:36,320
yeah, it's been, it's been really long. And again, I mean, if this had been like this multiple times

56
00:05:36,320 --> 00:05:41,920
a day, I mean, we'd probably fix it sooner or found out ways to address it sooner. The fact

57
00:05:41,920 --> 00:05:46,800
that it was just initially a couple of times a month is something you just effectively ignore,

58
00:05:46,800 --> 00:05:52,080
right? If a service hangs twice a month, you just restart it, right? It's not great,

59
00:05:52,080 --> 00:05:57,440
but it's also not terrible. You know, especially in hindsight, how much time we sunk into fixing

60
00:05:57,440 --> 00:06:01,760
this up. If I had to make that choice again, twice a month or trying to figure this out,

61
00:06:01,760 --> 00:06:05,120
I mean, twice a month, I'll take that. That was easier.

62
00:06:06,320 --> 00:06:13,200
That's the blessing of async/await being adoptable slowly in that we could, you know,

63
00:06:13,200 --> 00:06:18,880
we did start to introduce it and replace it, first of all, in new code, and then started to replace

64
00:06:18,880 --> 00:06:25,120
bits as we touched a bit of code, you might convert it from event loops to async/await.

65
00:06:25,120 --> 00:06:29,760
But of course, the more we did that, the more it seemed to get, this problem got worse, right?

66
00:06:29,760 --> 00:06:34,000
Yes. Yeah. And I wouldn't change, I wouldn't make that trade either. I mean,

67
00:06:34,000 --> 00:06:39,840
I'm happy we made that change to async/await. It just makes maintaining the code much nicer.

68
00:06:39,840 --> 00:06:45,200
We should be very clear here and say that we're not saying that task groups are bad.

69
00:06:45,200 --> 00:06:54,160
I think this is, I know we haven't logged a bug for this yet, because I think getting a reproducible

70
00:06:54,160 --> 00:06:57,840
case for this is going to be, I don't know, tricky.

71
00:06:57,840 --> 00:07:03,760
Yes. So I was going to get to that. We haven't reported that really, because it's effectively

72
00:07:04,080 --> 00:07:08,720
I wouldn't even know how to report that. You know, a task group on Linux in certain situations

73
00:07:08,720 --> 00:07:16,240
can cause hangs. I mean, if I got that bug report, I say, well, tell me more. And then I say, well,

74
00:07:16,240 --> 00:07:23,200
I can't really. So one of the things we tried to debug this was when the process hangs to send it

75
00:07:23,200 --> 00:07:29,920
a kill signal to get the stack trace. But the problem is with 5.9.0 right now, on Linux, you

76
00:07:29,920 --> 00:07:39,120
don't get symbolicated stack traces. There's a change that fixes that. That's going to go live

77
00:07:39,120 --> 00:07:49,920
with 5.9.1, I believe. And once that is live, I guess what we'll do is revert back to the task

78
00:07:49,920 --> 00:07:54,720
group, at least on dev, because it happened on both environments, and then just run it and see

79
00:07:54,720 --> 00:08:00,080
if we can get a stack trace out of it then to get more info on, you know, have at least something

80
00:08:00,080 --> 00:08:06,800
better to report than this nebulous. Yes. Hangs sometimes sort of report because no one can do

81
00:08:06,800 --> 00:08:13,040
anything with that, really. Because Gwyn is super experienced with this sort of stuff and

82
00:08:13,040 --> 00:08:21,760
was actually trying to read the stack trace that we got, the raw one, and sort of had some ideas.

83
00:08:21,760 --> 00:08:27,920
But I think we need more information for anyone else to be able to do more here.

84
00:08:27,920 --> 00:08:29,920
So even though it's fixed, it's not over.

85
00:08:29,920 --> 00:08:35,440
It's not over, no. But well, at least in terms of operationally, it's over. That's great. The

86
00:08:35,440 --> 00:08:40,400
performance hit wasn't actually as bad as I thought it'd be. I think it's 50 or 60%, something

87
00:08:40,400 --> 00:08:49,520
like that, which is okay. We have a little headroom there. We're not running the process

88
00:08:50,240 --> 00:08:55,600
back to back all the time. We have a little pause there because analysis is running fast enough for

89
00:08:55,600 --> 00:09:01,200
our purposes. So if we were uncomfortable with sort of this running a bit slow, we could reduce

90
00:09:01,200 --> 00:09:06,640
the delay and have the same throughput effectively. So that's not terrible either.

91
00:09:06,640 --> 00:09:14,160
Yeah, so I think we're all right there overall. It's also worth probably mentioning that the only

92
00:09:14,160 --> 00:09:21,360
thing this would delay is how quickly packages update after a new version is published. So

93
00:09:21,360 --> 00:09:25,360
we're currently running at like a couple of hours, something like that. So if,

94
00:09:25,360 --> 00:09:29,680
depending on how far through the cycle we are, you might get lucky and it might update

95
00:09:29,680 --> 00:09:36,560
almost immediately if your package was next in the update queue. But in worst case scenario,

96
00:09:36,560 --> 00:09:41,280
you're looking at a couple of hours of delay from pushing a new release to GitHub and

97
00:09:42,480 --> 00:09:50,240
the package page updating. So even if that doubled, I wouldn't be fretting too much.

98
00:09:50,240 --> 00:09:55,600
I would love it if every package immediately updated. Of course I would, that would be the

99
00:09:55,600 --> 00:10:01,920
best situation. But this is not something that really is going to affect most people. And this

100
00:10:01,920 --> 00:10:06,560
is only versions. The packages are all still there. So people searching for packages,

101
00:10:06,560 --> 00:10:11,840
using the package index, it's relatively minor in the grand scheme of things.

102
00:10:11,840 --> 00:10:18,640
Yes. And we do prioritize new packages for immediate analysis. So if you add a package,

103
00:10:18,640 --> 00:10:23,840
it'll be going to the front of the queue. So this only affects if you have releases

104
00:10:23,840 --> 00:10:29,920
and effectively means that going through all packages once now takes probably around six

105
00:10:29,920 --> 00:10:34,400
hours. I haven't actually measured it. It used to take four. We also have more packages these days.

106
00:10:34,400 --> 00:10:37,040
Oh my, my numbers are out of date then.

107
00:10:38,080 --> 00:10:45,840
Yeah. I haven't actually checked, but early on we had 3,000, I think it's 6,000 now. So

108
00:10:45,840 --> 00:10:51,760
we have double the packages and 50% slower processing. I would bet we've gone from

109
00:10:51,760 --> 00:10:57,200
three to four to maybe six hours or something like that, but it shouldn't be a huge problem.

110
00:10:57,200 --> 00:11:00,240
Sure. Yeah. Well, I'm glad it's fixed.

111
00:11:00,800 --> 00:11:08,320
Oh yeah, so am I. And pretty much in parallel to this, there was another problem that we

112
00:11:08,320 --> 00:11:14,160
started having recently, which interestingly was also a hang, but unrelated to this one,

113
00:11:14,160 --> 00:11:18,320
that was affecting our build system. Also there, it's unclear why that happened.

114
00:11:18,320 --> 00:11:26,240
It only affected Xcode builds like with the Xcode build command builds. So on Apple platforms,

115
00:11:27,600 --> 00:11:32,720
we have two ways of running builds. One is Swift PM and the other one is Xcode build,

116
00:11:32,720 --> 00:11:36,880
especially for the iOS, tvOS, watchOS, visionOS platforms.

117
00:11:36,880 --> 00:11:43,760
And I'm not sure if it was all packages, but many packages, when they had a build failure,

118
00:11:43,760 --> 00:11:53,440
they would hang. And to the best of our understanding, this is a OS update potentially

119
00:11:53,440 --> 00:11:58,560
that caused that because we had no related build changes that would cause that to happen.

120
00:11:58,560 --> 00:12:06,960
And yeah, that's also something we fixed, sort of inherited another fix that helped out in this

121
00:12:06,960 --> 00:12:12,880
case as well. So it was a big week or two weeks since we last recorded.

122
00:12:12,880 --> 00:12:20,640
Yeah. And this was actually causing us capacity issues with the build system because the builds

123
00:12:20,640 --> 00:12:26,160
that were hanging were then holding up other builds in the queue. And we got into a situation

124
00:12:26,160 --> 00:12:33,200
where our build system was unable to keep up with the influx of new releases and versions,

125
00:12:33,200 --> 00:12:38,160
which is the first time that's happened really. And of course, with our current hardware, that

126
00:12:38,160 --> 00:12:42,800
was going to happen at some point because the number of packages and the number of releases

127
00:12:42,800 --> 00:12:53,280
keeps increasing. But yes, it was a little bit of a panic stations where when the queue of pending

128
00:12:53,280 --> 00:12:59,440
builds was only going up and not really coming down very much. And I should mention that Max

129
00:12:59,440 --> 00:13:08,400
Stadium helped us out with, before we figured out the bug, just to help us keep that backlog under

130
00:13:08,400 --> 00:13:13,920
control. They very, very kindly, temporarily gave us an extra machine so that we could keep on top

131
00:13:13,920 --> 00:13:18,640
of the backlog. Yeah, that was great. That helped so much because if you sort of have to fix

132
00:13:18,640 --> 00:13:24,160
something and at the same time, keep an eye on a queue that's filling up, it's just not great.

133
00:13:24,160 --> 00:13:29,200
So having that sort of relief, at least it's working again, because also now the build system

134
00:13:29,200 --> 00:13:35,200
is doing the documentation building. So it's kind of getting additional responsibility. And also

135
00:13:35,840 --> 00:13:41,680
people are relying on that more if we look at our stats and documentation page views,

136
00:13:41,680 --> 00:13:46,480
that's going up. So people are relying on the docs more and more and having issues in the

137
00:13:46,480 --> 00:13:54,640
build system that also affect the documentation generation just isn't great. So I'm really glad

138
00:13:54,640 --> 00:14:03,440
that those two issues are fixed and sort of freeze us up again. And again, just to be super,

139
00:14:03,440 --> 00:14:10,080
super clear, none of this affects the hosting of that documentation. It's all only about how

140
00:14:10,080 --> 00:14:15,600
quickly that documentation and the package pages get updated after a new release. Yeah, exactly.

141
00:14:15,600 --> 00:14:26,160
So yeah, a couple of weeks of bugs. Yeah. Talking of the build system, I noticed a package get added

142
00:14:26,160 --> 00:14:31,680
to the index this week, which I think we've talked about Windows compatibility before, but the

143
00:14:32,640 --> 00:14:44,880
package is Swift WinRT by Salim Abdul Rasool. And this is a package that allows you to hook into the

144
00:14:44,880 --> 00:14:55,360
Windows runtime APIs on Windows, of course, from Swift. And the reason that I bring this up with

145
00:14:55,360 --> 00:15:04,400
the build system is this is obviously a very interesting package. It enables native Windows

146
00:15:04,400 --> 00:15:13,680
development with Swift, which is quite a thing. That is a major step forward in terms of cross

147
00:15:13,680 --> 00:15:22,160
platform Swift. And that is not to say that it's allowing Apple technologies like Swift UI and UI

148
00:15:22,160 --> 00:15:27,920
kit to run on Windows. That's not what this is. This is if you want to build a native Windows

149
00:15:27,920 --> 00:15:35,040
application with Swift, this package will help you do that. But the downside is if you look at

150
00:15:35,040 --> 00:15:40,400
the compatibility matrix for that package, it is full of gray crosses, which means that there's

151
00:15:40,400 --> 00:15:45,360
nothing compatible. And the reason for that is that we don't have Windows compatibility testing

152
00:15:45,360 --> 00:15:52,080
yet. And the more that happens on Windows, the more urgent this problem of do we tackle

153
00:15:52,080 --> 00:15:57,040
compatibility testing for Windows, the more important that becomes.

154
00:15:57,040 --> 00:16:00,640
Koen Smeets Yeah, it's I mean, it's going to happen at

155
00:16:00,640 --> 00:16:06,800
some point, right? I'm just peeking through the gap between my two screens here and I see my old

156
00:16:06,800 --> 00:16:18,320
Intel MacBook. And I think it's going to see a new life as perhaps a Windows test machine.

157
00:16:18,320 --> 00:16:23,200
Jason Vale Well, we could run the test machines.

158
00:16:23,200 --> 00:16:27,200
Koen Smeets No, just to try it, right? I've never run

159
00:16:27,200 --> 00:16:34,080
or done anything with Swift on Windows. I mean, it's just Mac OS and Linux.

160
00:16:34,080 --> 00:16:34,640
Jason Vale Neither have I.

161
00:16:34,640 --> 00:16:36,480
Koen Smeets I don't have a whole lot of

162
00:16:36,480 --> 00:16:46,160
Windows experience either. I stopped using Windows in 1991 in earnest. So I shy away a bit from it,

163
00:16:46,160 --> 00:16:52,000
to be honest, even installing it and getting into it. I know we're going to have to at some point,

164
00:16:52,000 --> 00:16:58,960
but it's so out of my comfort zone that I'm currently trying to find other things to do.

165
00:16:58,960 --> 00:17:02,560
Jason Vale Yeah, I mean, we could run the

166
00:17:02,560 --> 00:17:08,640
servers, no problem. The rest of our infrastructure, the build machines that do not run on

167
00:17:08,640 --> 00:17:13,840
Mac Stadium, they run on Microsoft Azure. So if there's one place you can run Windows machines

168
00:17:13,840 --> 00:17:25,040
reliably, it's Azure. So that's not a problem. The issue is building that, you know, taking

169
00:17:25,040 --> 00:17:31,360
advantage of Windows or not even taking advantage, just getting it working with Windows is going to

170
00:17:31,360 --> 00:17:34,080
be the issue. But we have to tackle it. We have to.

171
00:17:34,080 --> 00:17:35,920
Koen Smeets Yeah, yeah. Yeah, it's going to be

172
00:17:35,920 --> 00:17:41,840
interesting. Also integrating it into our build system, which is even between Mac and Linux,

173
00:17:41,840 --> 00:17:47,840
there are huge differences in how we operate those and Windows will have yet another way,

174
00:17:47,840 --> 00:17:57,680
potentially, of how to do that, I suppose. I mean, it kind of depends on how that works. I guess,

175
00:17:57,680 --> 00:18:02,400
you know, it's only SwiftPM build. So I guess, and probably not Dockerize. Well, I'm pretty sure

176
00:18:02,400 --> 00:18:07,760
it's not Dockerize. So it'll probably mirror how we do the macOS builds. But it's going to take

177
00:18:07,760 --> 00:18:14,240
some figuring out how to do that, how to run the machinery, we need to schedule the builds and all

178
00:18:14,240 --> 00:18:19,280
that stuff on Windows and all that. So it's, it's, yeah, it's going to take some typing.

179
00:18:19,280 --> 00:18:22,080
Jason Vale It's also, and this is, this is clearly

180
00:18:22,080 --> 00:18:26,720
the biggest issue of all, is it's also going to need a redesign of that compatibility matrix,

181
00:18:26,720 --> 00:18:32,480
because we're absolutely squished right to the very edge of what fits on that matrix right now.

182
00:18:32,480 --> 00:18:37,760
So clearly, that's the biggest issue of them all, the design of it.

183
00:18:37,760 --> 00:18:42,320
Richard Pinchot We should probably start there. And I'll wait.

184
00:18:42,320 --> 00:18:47,920
Jason Vale

185
00:18:47,920 --> 00:18:51,440
Yes, but it certainly, it would be lovely to see a green tick there.

186
00:18:51,440 --> 00:18:53,040
Richard Pinchot Definitely. Yeah, definitely.

187
00:18:55,040 --> 00:18:59,680
In terms of that wasn't a real package pick now, was it? That was that was still?

188
00:18:59,680 --> 00:19:02,000
Jason Vale It wasn't. That was just,

189
00:19:02,000 --> 00:19:05,360
that was just talking about packages. Yeah, exactly. Yeah.

190
00:19:05,360 --> 00:19:07,600
Richard Pinchot I have, I'm sort of in a similar situation,

191
00:19:07,600 --> 00:19:15,680
because I have a package pick that came out of a, a, another thing that I saw on Mastodon. And that

192
00:19:15,680 --> 00:19:22,880
is perhaps something we could briefly talk about. And it's a dev tool, breadcrumbs by

193
00:19:22,880 --> 00:19:29,760
Marin Todorov. He, he's doing these great little experiments with dev tools. I mean,

194
00:19:29,760 --> 00:19:34,640
he's also released some dev tools in the past, but currently, he's sort of using SwiftUI to

195
00:19:34,640 --> 00:19:39,360
prototype stuff. And it's really great to follow along what he's doing. And that kind of made me

196
00:19:39,360 --> 00:19:46,640
think, Dave, when's the last time you came across a new Mac OS dev tool that really embraced the

197
00:19:46,640 --> 00:19:50,320
platform? Can you can you recall something really new?

198
00:19:50,320 --> 00:19:54,800
Dave Bates Yeah, I, you asked me this question before,

199
00:19:54,800 --> 00:19:59,520
there's a bit of a bit of background to this, you asked me this question before the, the show, and

200
00:19:59,520 --> 00:20:04,480
the only one I could come up with was Reveal, which is definitely not new, but it has just had

201
00:20:04,480 --> 00:20:09,200
a new release. Yeah. And that is, you know, for all intents and purposes, as far as we know,

202
00:20:09,200 --> 00:20:19,360
a successful developer tool. It shouldn't be a difficult market, because the people who Marin

203
00:20:19,360 --> 00:20:26,400
already knows should be his target audience for these tools. And there should be an audience,

204
00:20:26,400 --> 00:20:33,520
a ready made market for developers to make developer tools that that make viable or,

205
00:20:33,520 --> 00:20:36,560
you know, doesn't have to be a complete viable business, but you know, certainly

206
00:20:36,560 --> 00:20:42,720
support the development of the tool. And I don't really know why that's not possible,

207
00:20:42,720 --> 00:20:48,320
but I agree, it's not really happening. The the other one that I, that springs to mind is

208
00:20:48,320 --> 00:20:55,200
Kaleidoscope, which is, again, not new, but has recently changed hands again, and is receiving

209
00:20:55,200 --> 00:21:00,160
significant kind of development updates regularly, you know, almost every, every few weeks, they put

210
00:21:00,160 --> 00:21:04,640
out a new version with some new feature, which, honestly, it's a fantastic tool. It's really,

211
00:21:04,640 --> 00:21:10,880
it's a really great diff tool, if you if you haven't checked it out. And, and that the,

212
00:21:10,880 --> 00:21:17,440
the pricing of that is certainly, you know, subscription pricing. So it should be sustainable,

213
00:21:17,440 --> 00:21:22,160
it should be enough to build a business on the back of, but it is a tough market to get into

214
00:21:22,160 --> 00:21:26,080
at the moment. And that's a perfect example, because I have that in my notes, Kaleidoscope,

215
00:21:26,080 --> 00:21:32,160
I use it effectively every day. I am on Kaleidoscope three, because I've looked at the

216
00:21:32,160 --> 00:21:40,160
feature list of four, the one that changed to subscription pricing. And I sort of struggled

217
00:21:40,160 --> 00:21:44,480
to see the value proposition a bit in my particular case, I don't even know, I don't

218
00:21:44,480 --> 00:21:49,200
remember what the differences were. But when I looked at it, I thought, yeah, I think, you know,

219
00:21:49,200 --> 00:21:55,120
what would make me switch is, you know, if an OS update sort of made three not work anymore,

220
00:21:55,120 --> 00:22:00,720
and understand that is actually a feature that that you need to pay for, you know, maintenance

221
00:22:00,720 --> 00:22:05,040
of a tool that, you know, changes across OS versions. And I'm happy to do that at some

222
00:22:05,040 --> 00:22:11,360
point. It's just that right now, I didn't make a switch yet. And I think a lot of that is because

223
00:22:11,360 --> 00:22:18,160
our expectations around pricing have changed so much with the effectively the pricing

224
00:22:18,160 --> 00:22:26,240
development on the App Store, right? We've sort of been trained to expect lower and lower prices.

225
00:22:26,240 --> 00:22:34,160
If I told my past self, you know, like, 10, 20 years ago, there's a dev tool that costs 100 euros

226
00:22:35,360 --> 00:22:41,440
per year. Yeah, that's, that's normal business. And but it's not anymore. It's like,

227
00:22:41,440 --> 00:22:50,080
it really stands out as a as a price. And it shouldn't but we and it's really hard, even if

228
00:22:50,080 --> 00:22:56,000
if you are thinking about this, you are affected by these low prices, because that's what you

229
00:22:56,000 --> 00:23:02,560
compare it to. And it's really bizarre. And at the same time, you know, we lament this decline

230
00:23:02,560 --> 00:23:06,320
in tools. I can't last thing I could think of that I bought was Nova,

231
00:23:06,320 --> 00:23:12,400
which also isn't new, right? They're on version for something, I believe, but I only just started

232
00:23:12,400 --> 00:23:20,240
using it recently. It's we lament the absence of these tools. At the same time, we are all

233
00:23:20,240 --> 00:23:27,840
sort of affected by the low prices and sort of don't then chip in when there are tools that are

234
00:23:27,840 --> 00:23:34,560
certainly worth it. It's, it's, it's a really bizarre situation. And clearly, I mean, I think

235
00:23:34,560 --> 00:23:39,840
if, if the market was better, some of these experiments, you know, that Marin is, is making

236
00:23:39,840 --> 00:23:46,000
would probably turn into proper products. But I mean, I don't know. But I think the main reason

237
00:23:46,000 --> 00:23:52,560
he isn't wrapping them up and publishing them because and I know he tried it with a couple

238
00:23:52,560 --> 00:23:58,160
of things in the past is that they don't tend to be sustainable in the end. I mean, I know from my

239
00:23:58,160 --> 00:24:04,160
little app that I have, which isn't effectively a dev tool, but a window management tool that is,

240
00:24:04,160 --> 00:24:10,800
that's nowhere near something that would sustain any sort of indie career. It's

241
00:24:10,800 --> 00:24:18,880
just doesn't happen. And I have a dev tool as well on the App Store, an Xcode plugin. It's nothing,

242
00:24:18,880 --> 00:24:24,480
there's just nothing happening. And I don't do any marketing. So there's no surprise, but it's

243
00:24:24,480 --> 00:24:31,600
also not, this isn't happening on its own. So there's clearly something off.

244
00:24:31,600 --> 00:24:35,120
Toby I think this also comes into the whole

245
00:24:35,120 --> 00:24:40,400
subscription pricing thing. Like you just said it then, that if somebody said to you,

246
00:24:42,800 --> 00:24:49,520
this tool that you use and rely on is going to be a hundred pounds per year. And you say, well,

247
00:24:49,520 --> 00:24:58,960
that's a decision I can make yes or no on that. And the old way of doing it would be that you

248
00:24:58,960 --> 00:25:04,400
pay the money and then a year later or something like that, you pay some more money for an upgrade

249
00:25:04,400 --> 00:25:09,040
to the latest version of it or whatever like that. That worked for many, many years. And there's

250
00:25:09,920 --> 00:25:16,160
actually very little difference between that model and the subscription model apart from that you

251
00:25:16,160 --> 00:25:23,040
lose access to the running piece of software that you currently have with the subscription model.

252
00:25:23,040 --> 00:25:31,440
And in reality, that I don't think is a huge issue, but mentally that is an enormous blocker

253
00:25:31,440 --> 00:25:37,760
because you feel like, well, I'm paying for this thing and therefore, and I'm not saying this is

254
00:25:37,760 --> 00:25:42,800
the correct, you know, there's no such thing as a correct opinion here, but there is something

255
00:25:42,800 --> 00:25:48,400
fundamental in us that says, well, I'm paying for this thing, therefore I should own this thing.

256
00:25:48,400 --> 00:25:56,800
And that switch to subscriptions is in reality is a very trivial switch for the actual amounts

257
00:25:56,800 --> 00:26:02,800
of money that change hands. But that there's something in our brains that doesn't like that

258
00:26:02,800 --> 00:26:03,120
switch.

259
00:26:03,120 --> 00:26:09,600
Yes. And there's actually, I mean, if I just think about it, there's a great argument for

260
00:26:09,600 --> 00:26:17,840
subscription pricing is I don't really love it when software sort of comes up with point releases

261
00:26:17,840 --> 00:26:24,240
to charge money and features that really don't do anything right. There's that happening as well as

262
00:26:24,240 --> 00:26:30,080
just feature creep for the purpose of being able to charge someone. I'd actually rather pay for

263
00:26:30,080 --> 00:26:35,200
just plain maintenance and picking features that make sense rather than give it all sorts of bells

264
00:26:35,200 --> 00:26:39,760
and whistles that have no business of being there other than, all right, I need to charge you

265
00:26:39,760 --> 00:26:45,760
something. So I need to ship something. And that's also a weird business model, right?

266
00:26:45,760 --> 00:26:52,000
But we are, it's this subscription fatigue is real. If you have this feeling, right,

267
00:26:52,000 --> 00:26:57,120
I've signed up for this and then everything hits me. I often sign up for stuff and then

268
00:26:57,120 --> 00:27:04,320
immediately cancel it. So I don't, I hate it when stuff renews and I forgot about it. So, yeah.

269
00:27:04,320 --> 00:27:12,240
Yes. I do the same. I also set reminders in my calendar to say, cancel this a year. Let's say

270
00:27:12,240 --> 00:27:16,480
I pay for a year or something and I put a reminder in saying like, it's not necessarily cancel it,

271
00:27:16,480 --> 00:27:23,920
but just like make that decision. Did this pan out or not? So my calendar, my reminders folder

272
00:27:23,920 --> 00:27:29,760
is full of those. Before we move on from this topic, I should just mention for disclosure,

273
00:27:29,760 --> 00:27:36,560
I do, I did receive a copy of Kaleidoscope for free. I reviewed it for iOS Dev Weekly. So

274
00:27:36,560 --> 00:27:42,000
just to disclose that that is the case that I did receive a free copy of that.

275
00:27:42,000 --> 00:27:45,840
Cool. Is it package time then?

276
00:27:45,840 --> 00:27:50,480
I think it is. We've, I think we were chatting before the show saying we've not got much to

277
00:27:50,480 --> 00:27:57,040
talk about and here we are 32 minutes in already. So let's, let's maybe keep it a short set of

278
00:27:57,040 --> 00:27:58,160
packages this week.

279
00:27:58,160 --> 00:28:00,160
Let's do that. Do you want to kick us off?

280
00:28:00,160 --> 00:28:08,240
Sure thing. I will kick us off with a package called Grape by Zhen Li. I actually linked to this

281
00:28:08,240 --> 00:28:16,080
in iOS Dev Weekly a couple of weeks ago. This is a visualization packages for connected nodes

282
00:28:16,080 --> 00:28:23,200
of information. You might have seen this quite often runs in JavaScript. In fact, I,

283
00:28:23,200 --> 00:28:30,560
I forget the name of it now, but there was a, a Swift, an application written in Swift that

284
00:28:30,560 --> 00:28:37,920
inspected Swift dependencies and displayed them in this format of, of, of charts. And it's kind

285
00:28:37,920 --> 00:28:46,640
of like an animated node graph where there are a whole load of dots on the canvas and then each

286
00:28:46,640 --> 00:28:50,880
dot is connected. So one dependency would be connected to another dependency or whatever it

287
00:28:50,880 --> 00:28:56,800
is that you're modeling. And then they have, they all have kind of a little bit of physics

288
00:28:56,800 --> 00:29:03,520
applied to them. So as they settle, they, the dots kind of push each other apart a little bit,

289
00:29:03,520 --> 00:29:07,440
and then you can normally, you can, you can interact with them, pull them apart,

290
00:29:07,440 --> 00:29:12,880
inspect them, click in, maybe navigate through to you know, through a hierarchy of dependencies

291
00:29:12,880 --> 00:29:17,280
or something like that. Anyway, that's, I'm sure if you, if you have a look at the,

292
00:29:17,280 --> 00:29:21,680
the readme file, you'll recognize immediately this style of visualization.

293
00:29:21,680 --> 00:29:28,000
But as I say, everything I've seen so far has been doing this in JavaScript. And in fact,

294
00:29:28,000 --> 00:29:33,200
even the Swift application that I mentioned before, that, that, that booted up, as far as I

295
00:29:33,200 --> 00:29:40,720
know, it booted up a web view and then visualized it within the web view. This is a Swift native

296
00:29:40,720 --> 00:29:50,400
implementation of that. And it looks great. This is the kind of thing that if you need this kind

297
00:29:50,400 --> 00:29:57,360
of display, then you should absolutely check this package out. Great. That sounds great.

298
00:29:58,000 --> 00:30:04,720
Um, right. My first pick this week is called Firefly. And this is the package I alluded to

299
00:30:04,720 --> 00:30:10,320
earlier. It's a dependency that Marin Todorov is using in his little prototype Breadcrumbs.

300
00:30:10,320 --> 00:30:17,600
And so just to explain what Breadcrumbs actually does, Breadcrumbs is a little experiment,

301
00:30:17,600 --> 00:30:24,720
a Mac app that looks for to do and fix, fix it or fix me markers rather in, in Xcode projects.

302
00:30:25,360 --> 00:30:31,280
So you have a little viewer of those, um, and, uh, it shows the marker and some context around

303
00:30:31,280 --> 00:30:36,640
it. And you can click on that and it brings up the file in Xcode. Uh, so you can, you know,

304
00:30:36,640 --> 00:30:42,480
sort of traverse your project for to do's and fix it, get a view of you could effectively use them

305
00:30:42,480 --> 00:30:47,360
as, as little to do items, sprinkle throughout the code without actually needing to set up

306
00:30:47,360 --> 00:30:52,960
anything other than putting those markers in which you probably have anyway. Um, and that's a nice

307
00:30:52,960 --> 00:30:57,840
little tool. And in his main view where he's showing this, the context around the to do like

308
00:30:57,840 --> 00:31:04,400
Swift code, um, that syntax highlighted and Firefly is the syntax highlighter that Marin is using

309
00:31:04,400 --> 00:31:10,720
in his project. Um, and this is nice. I think we've mentioned syntax highlighting packages

310
00:31:10,720 --> 00:31:16,720
in the past, and they've all been based on, I believe, JavaScript libraries that was embedded

311
00:31:16,720 --> 00:31:23,760
in, in, um, uh, what's the, what's the framework. Do you know, uh, is it JS core is the framework,

312
00:31:23,760 --> 00:31:29,120
right? That's being used to absorb those. Um, but this is a pure Swift package, so there's

313
00:31:29,120 --> 00:31:34,720
no fiddling with JavaScript wrappers or anything. Um, you know, that usual packaging of it, it's a

314
00:31:34,720 --> 00:31:40,400
pure Swift package and you can just run the code through it and you get a view and you can display

315
00:31:41,040 --> 00:31:47,200
the, um, highlighted, uh, syntax highlighted text. So that's, um, oh, I didn't actually say

316
00:31:47,200 --> 00:31:51,600
the author that's Taylor Lineman is the author Firefly by Taylor Lineman.

317
00:31:51,600 --> 00:31:58,480
Jason Vale – That sounds great. Yeah. And just to also talk about that, um, uh, the app that,

318
00:31:58,480 --> 00:32:02,960
uh, Marin was using it. And I think that's, it's a great idea for an application. I'm not sure it

319
00:32:02,960 --> 00:32:07,600
supports subscription pricing, but it's a great idea. And I know that we have a whole load of

320
00:32:07,600 --> 00:32:11,680
to-dos in our, um, in our code base that it would surface.

321
00:32:11,680 --> 00:32:15,440
Daniel Zeiss Well, it's the app is open source

322
00:32:15,440 --> 00:32:21,440
right now. So, um, you can subscribe by, um, I'm not sure if Marvin has a sponsor button on his

323
00:32:21,440 --> 00:32:25,840
GitHub, but, uh, if you are so inclined and he does, that's the way to do that.

324
00:32:25,840 --> 00:32:27,040
Jason Vale – If he doesn't, he should have.

325
00:32:27,040 --> 00:32:29,680
Daniel Zeiss Yeah, he definitely should. He definitely,

326
00:32:29,680 --> 00:32:36,080
he might. If he does, we'll add a link to the show notes and, uh, then you can head over and support

327
00:32:36,080 --> 00:32:36,580
him.

328
00:32:36,980 --> 00:32:44,260
Jason Vale – I haven't yet tried his app, but I did see, um, I think I saw it actually in a Slack.

329
00:32:44,260 --> 00:32:47,220
Um, he posted a screenshot of it somewhere as well.

330
00:32:47,220 --> 00:32:48,520
Yeah.

331
00:32:48,520 --> 00:32:59,940
My next package is pretty niche. Um, it's by Leon Hoppe and, uh, it's called Swift ISO 8601

332
00:33:00,500 --> 00:33:09,940
duration parser. So for many years, um, before foundation added an 8601 date parser, uh, there

333
00:33:09,940 --> 00:33:16,820
was a very popular package for parsing these 8601 dates, um, because it's a common format, um, in,

334
00:33:16,820 --> 00:33:25,060
in many web APIs. In fact, I would say it is the default date format in most, um, uh, web APIs.

335
00:33:25,060 --> 00:33:32,660
Um, but then Apple added to foundation and ISO 8601, uh, uh, compatible formatter and

336
00:33:32,660 --> 00:33:40,180
all our problems were solved. Um, until this week, I didn't realize that there was a new type or not,

337
00:33:40,180 --> 00:33:46,580
it's not new at all, but, uh, a different type of ISO 8601, um, uh, date related formatting.

338
00:33:46,580 --> 00:33:53,860
And that is you can format durations in 8601 as well. So you could say, for example,

339
00:33:54,820 --> 00:34:06,900
uh, PT 12H is 12 hours. Uh, P3D is three days, uh, P3D T12H is three days, 12 hours. And this is

340
00:34:06,900 --> 00:34:13,380
actually quite a useful format. I didn't even know this existed until I spotted this package, uh,

341
00:34:13,380 --> 00:34:21,140
the last week. Um, and, uh, Leon has put together a parser for, in fact, Leon put together a parser

342
00:34:21,140 --> 00:34:25,700
for it five years ago. It's been in development for a long time. Uh, I just hadn't spotted it

343
00:34:25,700 --> 00:34:31,860
until now. Nice. Interesting. I did not know that was actually specified out. I mean, we've

344
00:34:31,860 --> 00:34:39,060
sort of kind of, you'd kind of think like 3D, 3W and stuff like that is sort of the common way,

345
00:34:39,060 --> 00:34:44,420
but you're saying, right, there's a P prefix to these that makes it sort of more, a more stable

346
00:34:44,420 --> 00:34:50,260
format. Did I get that right in your description? Pretty much. Yeah. Yeah. Although also it's,

347
00:34:50,260 --> 00:34:56,180
it's more than that because it's, uh, because the, the, the three days, 12 hours one is P3D,

348
00:34:56,180 --> 00:35:02,020
which is the P whatever that means and the 3D, but then there's a T12 hours. So it's,

349
00:35:02,020 --> 00:35:07,700
there's more to the format than just a number of the letter P and then three, 3D 12H. Um,

350
00:35:07,700 --> 00:35:12,020
I'm not, I'm not sure that there is a link to Wikipedia. I haven't clicked it.

351
00:35:12,020 --> 00:35:18,980
P is the duration designate of period. Okay. Place at the start of the duration representation

352
00:35:19,700 --> 00:35:24,580
T is the time designator that precedes the time components in a representation. Okay.

353
00:35:24,580 --> 00:35:30,260
Interesting. Nice. Thank you. Thank you. Wikipedia.

354
00:35:30,260 --> 00:35:36,180
There's another subscription. I, I, I, I subscribe to Wikipedia every year.

355
00:35:36,180 --> 00:35:47,060
My second pick is a package called auto merge dash Swift by Joe Heck. Um, I actually thought

356
00:35:47,060 --> 00:35:51,300
we talked about this in the past that we might've mentioned it, but I didn't find it in our,

357
00:35:51,300 --> 00:35:58,660
our previous show notes. Um, so if we have, the reason I'm bringing it up again is that Joe has

358
00:35:58,660 --> 00:36:05,060
published a blog post announcing the latest release of the package and what's new, I think,

359
00:36:05,060 --> 00:36:11,700
apart from it being, I think more sort of on the road to feature complete is that he's added a,

360
00:36:11,700 --> 00:36:18,340
an example app that actually uses the library, um, a little app to manage meeting notes. Um,

361
00:36:18,340 --> 00:36:28,420
and the package is a, a library for CR DTs, which are conflict free replicated data types.

362
00:36:28,420 --> 00:36:37,140
So this is a, a tool for building or library for building collaborative systems where you can have

363
00:36:37,140 --> 00:36:42,420
data types that you can distribute, you know, people can edit them independently and then they

364
00:36:42,420 --> 00:36:48,500
can be merged. And there's, so the way that it's promised to be conflict free. So you won't,

365
00:36:48,500 --> 00:36:53,940
you won't run into merge conflicts, um, due to the magic of this library. I'm not sure if it's,

366
00:36:53,940 --> 00:37:01,460
if it's ruled out categorically by ways of how the algorithm works. Um, I think it is,

367
00:37:01,460 --> 00:37:06,820
I'm not a hundred percent sure. I've read quite a bit about them, but it's, it's a big field.

368
00:37:06,820 --> 00:37:13,220
There's lots of different ways of implementing them. Auto merge is one way of implementing them.

369
00:37:13,220 --> 00:37:19,220
And what's interesting here is there is actually an underlying library, Rust library that powers

370
00:37:19,220 --> 00:37:26,740
this, and this is a swift adaptation of it, or I think a wrapper around it. So it's a API layer

371
00:37:26,740 --> 00:37:32,020
that uses the Rust library. I believe I need to, I didn't actually delve into it that deeply.

372
00:37:32,020 --> 00:37:39,540
And the interesting part is that, um, because it's a Rust library and then also available for

373
00:37:39,540 --> 00:37:45,700
other platforms, it gives you a better chance of developing a system where Apple platforms or

374
00:37:45,700 --> 00:37:52,660
Swift platforms are just one part of what's using that as an exchange format. The Rust library would

375
00:37:52,660 --> 00:37:57,620
work on other platforms as well. And you could then exchange, you know, the files and, and work

376
00:37:57,620 --> 00:38:02,580
with it across platforms, I guess, more easily than that would normally be the case. So really

377
00:38:02,580 --> 00:38:06,340
nice. And I really liked that there's an example app where you can play around with it and see how

378
00:38:06,340 --> 00:38:14,980
it works. Uh, and that's auto merge by Joe Heck. I, I have Joe's blog post on this library in my,

379
00:38:14,980 --> 00:38:19,220
uh, reading list for this week. So thanks for the, uh, thanks for the recap of that. I,

380
00:38:20,900 --> 00:38:23,540
I will still read it, but you saved me, you saved me half the job.

381
00:38:23,540 --> 00:38:27,620
There we go. Joe coming up for this Friday, I guess.

382
00:38:27,620 --> 00:38:35,700
But no, I know, I know that this has been a topic that has been on Joe's mind for a long time now.

383
00:38:35,700 --> 00:38:43,060
And so, uh, yeah, it's, it's great to see. And again, I, I am not, um, an expert on the

384
00:38:43,060 --> 00:38:49,220
intricacies of, uh, CRDTs. I kind of don't even know the acronym. I think it's CRDTs, right?

385
00:38:50,180 --> 00:38:57,620
Or is it CDRTs? That's how, that's how little CRDTs, that's how little of an expert I am on them.

386
00:38:57,620 --> 00:39:04,500
Um, but I also believe that they, that they are potentially immune to those two conflicts. I mean,

387
00:39:04,500 --> 00:39:11,140
that's the whole point, right? Yeah. Yeah. What I really want to happen, um, is that someone takes

388
00:39:11,140 --> 00:39:16,740
the previous pick Firefly and this auto merge library and builds a Markdown collaborative

389
00:39:16,740 --> 00:39:21,860
editor. And, um, I'm looking at you there, Marin, you're, you're apparently experimenting

390
00:39:21,860 --> 00:39:28,100
with prototypes right now. Just Joe might help as well. You all go off.

391
00:39:28,100 --> 00:39:33,540
Sub-ether edit. Do you remember sub-ether edit? Oh, yes. Yeah. Yeah. Yeah.

392
00:39:33,540 --> 00:39:38,740
So sub-ether edit was part of the reason that I bought a Mac.

393
00:39:38,740 --> 00:39:44,420
Yeah. Many people did. I was at a conference in, yeah, yeah, absolutely. I was, I remember

394
00:39:45,140 --> 00:39:52,020
vividly, I was at a conference in San Diego. Um, it was, um, O'Reilly's e-tech conference and,

395
00:39:52,020 --> 00:39:59,700
uh, this emerging technologies conference. And, um, I walked into the conference hall on

396
00:39:59,700 --> 00:40:03,700
the first night. It was, it was a strange layout to the conference and a strange schedule to the

397
00:40:03,700 --> 00:40:09,860
conference that the, the keynotes were on the evening of the first day. And then the conference

398
00:40:09,860 --> 00:40:14,900
started properly the next morning. So, and I remember walking into this hall and seeing.

399
00:40:14,900 --> 00:40:22,500
Yeah. So many people taking notes with, uh, sub-ether edit because it, it used Bonjour to

400
00:40:22,500 --> 00:40:28,900
connect. And so if somebody was, was using sub-ether edit in a room, you could automatically

401
00:40:28,900 --> 00:40:35,540
see the people around who were, who were also editing and everybody was editing, um, uh, the,

402
00:40:35,540 --> 00:40:41,940
the, the, their kind of joint conference notes on, uh, in this application. And at the time I was a,

403
00:40:41,940 --> 00:40:50,020
a Windows user, um, still. And, um, uh, I, before I left San Diego, I had, uh, gone into an Apple

404
00:40:50,020 --> 00:40:56,660
store and bought a Mac. Nice. This, this is, this is really part of what we were talking about

405
00:40:56,660 --> 00:41:02,820
earlier, right? These dev tools. I mean, would this happen today? I really, I wonder, right?

406
00:41:02,820 --> 00:41:07,940
It's, I mean, I'm don't recall sub-ether edit. Was it always free? No, I think that was a,

407
00:41:07,940 --> 00:41:13,380
I don't remember. It was paid. Yeah. Yeah. Such great tools.

408
00:41:13,380 --> 00:41:24,420
Yeah. And it was a great tool. And, and the, the, the richness of that app ecosystem on the Mac was

409
00:41:24,420 --> 00:41:30,900
absolutely the reason the platform was just, just flat out straight without, I say this without any

410
00:41:30,900 --> 00:41:36,020
hesitation, it was better. It was absolutely better because of that native application

411
00:41:36,020 --> 00:41:44,820
ecosystem. And partly, um, uh, the fact that everything moved towards the web and therefore

412
00:41:44,820 --> 00:41:49,540
electron became a thing. And, you know, that's, that's part of what happened,

413
00:41:49,540 --> 00:41:52,260
but I think it's more than that. Yeah. Well, text mate is the other thing,

414
00:41:52,260 --> 00:41:57,300
right? That was equally powerful in attracting people to the platform. I mean, I'm, I still

415
00:41:57,300 --> 00:42:03,220
have text mate up right now. It's, it's sort of my note taking scratch pad, um, or, you know,

416
00:42:03,220 --> 00:42:08,020
config file editing thing. So if you want the full, if you want the full story, it was a combination

417
00:42:08,020 --> 00:42:15,620
of sub-ether edit and text mate, because I was, I was also experimenting with, um, with Ruby at

418
00:42:15,620 --> 00:42:21,140
the time and, and Rails was just, Rails was like 0.5 version, 0.5 or something like that at the

419
00:42:21,140 --> 00:42:27,540
time. And there was an amazing, very famous video that, um, David Handmaier Hanson made at the time

420
00:42:27,540 --> 00:42:35,460
where he built a blog software, built some blog software with Rails using text mate, um, in like

421
00:42:35,460 --> 00:42:41,140
five minutes or something like that. And it was a great demo, really, really great demo. And, uh,

422
00:42:41,140 --> 00:42:45,940
text mate was a big part of why it was a great demo because it was the first editor I'd seen

423
00:42:45,940 --> 00:42:52,260
that had auto expanding snippets. And the comp, so I, I was already thinking about buying a,

424
00:42:52,260 --> 00:42:58,340
it wasn't only sub-ether edit. Sub-ether edit was the, the, the, the final straw, the last straw.

425
00:42:58,340 --> 00:43:04,740
Um, but text mate was, was there, text mate was, was the initial, initial kind of push towards it.

426
00:43:04,740 --> 00:43:08,580
And then, uh, sub-ether edit broke, uh, broke the camel's back.

427
00:43:10,660 --> 00:43:15,140
Nice. Yeah. I mean, they're great tools. Really great, great tools.

428
00:43:15,140 --> 00:43:22,740
Yeah, really. Yeah. So in, in, uh, most, before we, before we get more stories of, uh, of how we

429
00:43:22,740 --> 00:43:28,260
all got into this platform, let's wrap it up there, shall we? Um, we will be back in a couple of weeks

430
00:43:28,260 --> 00:43:34,660
with some more, um, news, hopefully no more bugs and, uh, of course some more package recommendations.

431
00:43:34,660 --> 00:43:37,300
So I will speak to you in a couple of weeks.

432
00:43:37,300 --> 00:43:39,700
Yep. See you in two weeks. Bye-bye.

433
00:43:39,700 --> 00:43:41,060
Alright, bye bye.