1
00:00:00,001 --> 00:00:02,720
Are you following the Euro, by the way, the football?

2
00:00:02,720 --> 00:00:11,680
I'm not a big football fan. I did watch the last half and the extra time and the penalties of the

3
00:00:11,680 --> 00:00:21,280
Switzerland game, though, which was very exciting. And I'm not a football fan, but I believe we don't

4
00:00:21,280 --> 00:00:26,320
have a great track record at penalties. I think we did exceptionally well in that Switzerland game.

5
00:00:26,320 --> 00:00:30,160
I was going to say England winning on penalties is quite the occasion.

6
00:00:30,160 --> 00:00:34,000
It's unheard of, right?

7
00:00:34,000 --> 00:00:40,560
Yeah, practically. And we're set up for my adopted country, France, possibly going up against

8
00:00:40,560 --> 00:00:44,480
England. Who knows? Although going past Spain...

9
00:00:44,480 --> 00:00:45,680
Oh, really? Is that what's next?

10
00:00:45,680 --> 00:00:46,560
Well, it's not next.

11
00:00:46,560 --> 00:00:48,400
I have no idea what the schedule is.

12
00:00:48,400 --> 00:00:55,200
France have to win against Spain, which is a tough one. And England will have to win against,

13
00:00:55,200 --> 00:01:00,160
and I'm blanking who their next opponent is. So yeah, there's still steps to go.

14
00:01:00,160 --> 00:01:04,160
But it might be a nice, interesting final.

15
00:01:04,160 --> 00:01:13,040
No, I've been watching more Wimbledon than I have football. But I think all the British names are

16
00:01:13,040 --> 00:01:17,360
even knocked out of Wimbledon by this point at this stage. So that's a shame.

17
00:01:17,360 --> 00:01:23,520
Yeah, the French as well, I believe. Yeah, just the last one dropped out yesterday. And

18
00:01:24,240 --> 00:01:26,560
I've been seeing a lot of rain in SW19.

19
00:01:26,560 --> 00:01:31,360
Yes, yeah, there has been a lot. In fact, I think I was reading the other day that they were going to

20
00:01:31,360 --> 00:01:36,560
consider reducing the length of some of the matches to try and fit it all in this week. So

21
00:01:36,560 --> 00:01:40,640
I don't know whether that's gone ahead or not, but that would be, I think,

22
00:01:40,640 --> 00:01:41,920
unprecedented if they do that.

23
00:01:41,920 --> 00:01:46,160
But how would they do that? Like up to four games only or super tie breaks?

24
00:01:46,160 --> 00:01:48,880
What's the solution there?

25
00:01:48,880 --> 00:01:54,960
Yeah, I think tie breaks after two matches were on the table.

26
00:01:54,960 --> 00:01:56,160
Oh, wow. Okay.

27
00:01:56,160 --> 00:02:02,480
So I don't know what the, sorry, not matches, sorry, two sets.

28
00:02:02,480 --> 00:02:05,520
Interesting. Well, let's see how it goes.

29
00:02:05,520 --> 00:02:14,320
But I'm not sure what the conclusion of that was. But you didn't tune into this podcast to learn

30
00:02:14,320 --> 00:02:20,240
about football or tennis, I hope, because you're in the wrong place if you have a football and

31
00:02:20,240 --> 00:02:32,160
tennis talk. What we can talk about this week is two blog posts, actually. So we published,

32
00:02:32,160 --> 00:02:40,480
first of all, a blog post on SWIFT.org about the Ready for SWIFT 6 project that we've been

33
00:02:40,480 --> 00:02:45,440
working on this summer. And I won't go into huge detail about that because we've talked about that

34
00:02:45,440 --> 00:02:51,920
at length on this podcast. But there is a blog post there that gives a bit of an overview about

35
00:02:51,920 --> 00:02:58,400
what we're doing and how we're representing that data on the package index package pages and things

36
00:02:58,400 --> 00:03:07,840
like that. And so that's up on the SWIFT Language blog, if you haven't yet checked out that page or

37
00:03:07,840 --> 00:03:10,960
are interested in some of the work that went in behind the scenes on that.

38
00:03:10,960 --> 00:03:21,280
And then the second blog post is one that we published just yesterday, which is about a new

39
00:03:21,280 --> 00:03:29,280
expansion to our build infrastructure that we use to do all of our compatibility build testing

40
00:03:30,080 --> 00:03:36,720
and documentation building and all of that. So we have, since the beginning,

41
00:03:36,720 --> 00:03:45,520
used a mixture of machines because we have Mac machines, which you need for performing

42
00:03:45,520 --> 00:03:54,320
the Apple platform builds, Mac OS, iOS and friends. And we run some Linux builds using

43
00:03:54,320 --> 00:04:01,840
Docker on Microsoft Azure, which is kind of separate, but all part of the same build system.

44
00:04:01,840 --> 00:04:13,280
And up until quite recently, we've had several Mac mini machines, just kind of bare metal,

45
00:04:13,280 --> 00:04:19,840
manually configured Mac mini machines that we've been running on. And they have been,

46
00:04:19,840 --> 00:04:27,280
I mean, they've been amazing. We started off with two Mac minis at the beginning, and

47
00:04:27,280 --> 00:04:35,040
they ran the initial set of builds, plus hosted the entire website at that point, didn't they?

48
00:04:35,040 --> 00:04:40,320
Yeah. And they were Intel Mac minis, right? Because that was actually quite a bit slower

49
00:04:40,320 --> 00:04:44,960
compared to the first M1 Mac mini we got once those came out.

50
00:04:45,760 --> 00:04:50,880
Yeah, we had the most overloaded web server ever when we first launched that build system,

51
00:04:50,880 --> 00:04:56,800
because it was trying to serve the web page and constantly process builds in the background.

52
00:04:56,800 --> 00:05:02,080
And over time, we have separated that out. The web server is no longer on

53
00:05:02,080 --> 00:05:09,680
that infrastructure anymore. That's running in Azure too. And the Mac mini machines became

54
00:05:12,400 --> 00:05:18,640
dedicated build machines that do nothing but build packages. And that was great. That was a

55
00:05:18,640 --> 00:05:25,120
great step forward. But of course, there's a couple of restrictions with that. First of all,

56
00:05:25,120 --> 00:05:32,240
it's all manually managed. So maintenance each week was making sure that the machines were still

57
00:05:32,240 --> 00:05:36,800
stable, because running hundreds and thousands and tens of thousands of builds per week

58
00:05:38,640 --> 00:05:45,520
on the same machines can be a source of instability. And making sure they're up to

59
00:05:45,520 --> 00:05:49,120
date with updates and all that kind of maintenance stuff that you have to do.

60
00:05:49,120 --> 00:05:58,880
But also, there were some limitations in that system. Because we were running each of those

61
00:05:58,880 --> 00:06:05,280
compatibility builds on the same machine as other compatibility builds, there was no kind of

62
00:06:05,280 --> 00:06:11,920
isolation between those environments. So we never hit insurmountable problems with this.

63
00:06:11,920 --> 00:06:18,160
But it was always a worry that either someone would find some way to break out of the Swift

64
00:06:18,160 --> 00:06:25,920
compiler sandbox and be able to do something to the Swift compiler that would disrupt or damage

65
00:06:25,920 --> 00:06:31,840
the machine. And thankfully, we never had that situation either. But again, that was always a

66
00:06:31,840 --> 00:06:40,080
worry. But secondly, just build environment isolation is a nice thing to have. To know that

67
00:06:40,080 --> 00:06:46,560
your build is not going to be impacted by something that some other build did at some point.

68
00:06:46,560 --> 00:06:57,680
So we had a really great system. And don't get me wrong, the system worked incredibly well

69
00:06:58,240 --> 00:07:06,800
for years. But it was never ideal. And in a conversation where we were talking to Macstadium

70
00:07:06,800 --> 00:07:15,440
about capacity, we ended up talking about their Orca system. So their Orca system is a

71
00:07:17,360 --> 00:07:25,280
Kubernetes system for virtualizing macOS. So I think it's Orchestration...

72
00:07:25,280 --> 00:07:31,600
What's the... Do you remember the abbreviation, the acronym?

73
00:07:31,600 --> 00:07:34,320
>> For Kubernetes? >> No, for Orca.

74
00:07:34,320 --> 00:07:38,160
>> Oh, the acronym. Oh, I'm sorry. No, I don't know. I don't know what Orca...

75
00:07:38,160 --> 00:07:41,440
Right, that isn't actually just the whale, is it?

76
00:07:41,440 --> 00:07:49,200
>> No, no. Well, I mean, it is a whale. It's VM Orchestration with Kubernetes on Apple.

77
00:07:49,200 --> 00:07:58,400
So they have this orchestration system for automating the creation and deletion of

78
00:07:58,400 --> 00:08:06,160
virtual machines on native Mac hardware in a kind of automated way. And so we ended up talking about

79
00:08:07,200 --> 00:08:14,720
that system with them and whether we could switch to an ephemeral build system, which is

80
00:08:14,720 --> 00:08:22,240
that every single build that we attempt gets a completely fresh VM, starts the VM up,

81
00:08:22,240 --> 00:08:28,800
executes the build, and shuts the VM down at the end of it. And that gives us total

82
00:08:28,800 --> 00:08:35,840
predictability because you're starting from the same exact place on every image every single time

83
00:08:35,840 --> 00:08:41,920
because the changes are not persisted back to the image. And it also gives us complete isolation,

84
00:08:41,920 --> 00:08:49,680
both from the impacts of other builds doing things to affect this build, but also of malicious builds.

85
00:08:49,680 --> 00:08:54,720
They would have to not only break out of the Swift compiler, but they would have to break

86
00:08:54,720 --> 00:09:01,920
out of a virtual machine as well, which I think is almost impossible. Never say anything security

87
00:09:01,920 --> 00:09:08,800
wise is impossible, right? But I think it's as good as. Yeah, absolutely. And I think one huge

88
00:09:08,800 --> 00:09:15,520
advantage, which we didn't have to do it often, but sometimes we had to run builds in the actual

89
00:09:15,520 --> 00:09:22,800
environment. And that was always, you know, it meant to SSH into one of the builders, pick the

90
00:09:22,800 --> 00:09:28,080
right one, check out stuff there. And, you know, you always sort of kind of worried, well, is this

91
00:09:28,080 --> 00:09:32,240
going to be different because I'm now doing it in a different directory than normally?

92
00:09:32,240 --> 00:09:38,720
You know, it's this here, we can just spin up the exact same copy of a machine,

93
00:09:38,720 --> 00:09:45,360
connect to it and run the build just as it normally would. And you can have really high

94
00:09:45,360 --> 00:09:49,280
confidence that you're actually looking at the same thing and debugging the same thing.

95
00:09:49,280 --> 00:09:56,560
And that's just a big help. But I think if you ask me what's the biggest advantage is beyond,

96
00:09:56,560 --> 00:10:01,440
you know, the maintenance that you already talked about, this debugging is actually our

97
00:10:01,440 --> 00:10:08,080
capacity management, because we now have the situation where every machine in the cluster

98
00:10:08,080 --> 00:10:14,720
can run any build. And previously, that was not the case. Every physical Mac that we had set up

99
00:10:14,720 --> 00:10:22,320
had a specific macOS version, and then one or two Xcode versions. I think that's sort of the maximum

100
00:10:22,320 --> 00:10:27,840
we ran with. But we sort of had to configure them in certain ways. And not every Xcode version can

101
00:10:27,840 --> 00:10:34,320
run on every macOS version. So we had to be, we had to choose what we deploy. And we never had a

102
00:10:34,320 --> 00:10:40,880
great mix where every Swift version was equally available across all machines. There was always

103
00:10:40,880 --> 00:10:45,440
one machine that was handling, like two Swift versions, where the other two were only handling

104
00:10:45,440 --> 00:10:50,320
one version. And you can imagine if lots of builds are coming in, that one machine will be struggling

105
00:10:50,320 --> 00:10:57,200
while the other two are underutilized. And that's great right now, because as soon as something

106
00:10:57,200 --> 00:11:04,400
shows up that needs building, any machine can participate. And not only that, it also means that

107
00:11:04,400 --> 00:11:11,280
in case we need more capacity, it's really easy to just add it in general, and it'll benefit all

108
00:11:11,280 --> 00:11:18,160
Swift versions. So we never need to worry about specifically setting up certain Swift versions

109
00:11:18,160 --> 00:11:22,800
and their availability anymore. And that's just a huge relief. And you see the benefit as we

110
00:11:22,800 --> 00:11:29,200
right now do our Swift 6 reprocessing. So over the summer, we're continuously hitting the system

111
00:11:29,200 --> 00:11:35,280
with lots and lots of builds of a very specific Swift version. We can just run full throttle,

112
00:11:35,280 --> 00:11:41,120
and we don't need to tweak anything about our setup. Like previously, we put up a couple of

113
00:11:41,120 --> 00:11:48,560
extra Swift 6 builders to help us deal with that immense backlog as soon as the new Swift 6 version

114
00:11:48,560 --> 00:11:54,720
came out. Now we don't have to, we just have everything available and we can just run with it.

115
00:11:54,720 --> 00:12:01,680
And that's just a huge relief. And that situation was quite extreme at times. Sometimes we needed

116
00:12:01,680 --> 00:12:09,840
three different host operating systems to run four different versions of Xcode. So at one point,

117
00:12:09,840 --> 00:12:16,800
we were running Monterey, Aventura, and Sonoma, with Monterey running one Xcode version, Sonoma

118
00:12:16,800 --> 00:12:20,960
running one Xcode version, and Aventura running two. I think that was when we were running five,

119
00:12:20,960 --> 00:12:32,720
six and above. So yeah, it was never even load. And now as part of this Orca system, we get to,

120
00:12:33,360 --> 00:12:42,560
on a job by job basis, say, let's spawn a Swift 5.7 build system, or let's spawn a Swift 5.10

121
00:12:42,560 --> 00:12:50,080
build system. And it comes up in a remarkably short amount of time. I did a little testing

122
00:12:50,080 --> 00:12:57,040
for the blog post as I was writing it. And the average time to spawn one of these VMs is three

123
00:12:57,040 --> 00:13:03,840
seconds, or in fact, under three seconds, it was like 2.8, 2.9 seconds, which I mean, I know it's

124
00:13:03,840 --> 00:13:09,520
not actually booting the machine, it's all saved state and it's just restoring that state into

125
00:13:09,520 --> 00:13:19,120
memory. But still, that is an impressive amount of time to have a fully usable, not container,

126
00:13:19,120 --> 00:13:25,040
but virtual machine running macOS. Yeah, I mean, I think they're sort of very similar because,

127
00:13:25,040 --> 00:13:29,360
you know, on macOS, if you run Docker, you're actually running a virtual machine.

128
00:13:29,360 --> 00:13:33,760
On Linux, it's a bit different, but just in terms of how you use it, if you're not familiar with

129
00:13:33,760 --> 00:13:39,840
Kubernetes and Orca is sort of a flavor of Kubernetes, I've not actually used pure,

130
00:13:39,840 --> 00:13:46,720
if you will, Kubernetes. But you can think of it just as if you were running a, or spinning up a

131
00:13:46,720 --> 00:13:51,760
Docker container here. That's effectively what we're doing, except it's Mac machines that are

132
00:13:51,760 --> 00:13:58,400
coming up and all the rest really behaves pretty much like that. And as my understanding is also

133
00:13:58,400 --> 00:14:04,400
like the Orca commands you run and the output you get is effectively like Kubernetes. So if you're

134
00:14:04,400 --> 00:14:11,200
familiar with Kubernetes, Orca will be really familiar to you, I believe. It's a really nice

135
00:14:11,200 --> 00:14:16,240
system. And we should talk a little bit about the hardware that's running as well, because the

136
00:14:17,920 --> 00:14:23,280
Mac minis that we had previously have had a little upgrade. And we're now running on...

137
00:14:23,280 --> 00:14:24,800
They've bucked up, yeah.

138
00:14:24,800 --> 00:14:34,160
Yeah, they certainly have in style too. We're now running on Mac Studio machines. So we're

139
00:14:34,160 --> 00:14:44,000
actually running M1 Mac Studio machines, but with M1 Ultra chips in them and 128 gig of RAM each.

140
00:14:44,960 --> 00:14:53,840
So what that actually means is because there is a limitation on all virtualization on Mac,

141
00:14:53,840 --> 00:15:02,560
and that is that Apple have a limitation of no more than two virtual instances of Mac OS

142
00:15:02,560 --> 00:15:07,760
running on a machine simultaneously. So what we're doing is we're splitting those Mac Studio

143
00:15:07,760 --> 00:15:18,320
machines straight down the middle with 10 cores per VM and 64 gig of memory per VM, which is still

144
00:15:18,320 --> 00:15:25,280
an enormous amount for a Swift compiler package. Even the largest packages are not going to run

145
00:15:25,280 --> 00:15:33,760
out of memory on our new VM based system. So yeah, and we have eight of those Mac Studio machines

146
00:15:34,480 --> 00:15:43,280
for a total of a terabyte of memory, which is kind of mind-blowing. And I think 160 cores

147
00:15:43,280 --> 00:15:53,040
of CPU processing, which gives us a total concurrency of 16 builds running at the same time.

148
00:15:53,040 --> 00:15:59,200
Yeah. And that's, as I said, the real shame that we can't boost that up a little higher.

149
00:15:59,200 --> 00:16:08,160
Yes. If anyone from Apple is listening, please drop us a kind word with whoever is responsible

150
00:16:08,160 --> 00:16:12,960
for that saying that we would really appreciate it because it's actually, it's worth talking

151
00:16:12,960 --> 00:16:20,480
about that for a second. We are able to, especially when we're doing these Swift 6

152
00:16:20,480 --> 00:16:25,680
processing runs where we fill up the backlog with a hundred thousand jobs ready to process,

153
00:16:25,680 --> 00:16:33,520
we are able to saturate our cluster with work to do for more than seven days of processing time.

154
00:16:33,520 --> 00:16:40,320
You know, we queue up a hundred thousand jobs and it takes about seven days to clear that backlog.

155
00:16:40,320 --> 00:16:52,320
And we had a look at the underlying CPU usage during that seven day period. And the underlying

156
00:16:52,320 --> 00:17:00,640
CPU usage was averaging out between 30 and 40% across the entire Mac Studio cluster.

157
00:17:00,640 --> 00:17:13,200
If we were able to spawn more VMs within our cluster, like more VMs per host,

158
00:17:13,200 --> 00:17:19,520
then we could even that out and drastically make our build environment more efficient.

159
00:17:20,240 --> 00:17:27,520
Because the build process has several stages. The build process is a Git checkout and then a Swift

160
00:17:27,520 --> 00:17:34,800
compile, and then a documentation build, possibly if your package author opts in, and then uploading

161
00:17:34,800 --> 00:17:40,800
that documentation to S3 and then reporting back results before kind of finishing the build.

162
00:17:40,800 --> 00:17:48,720
And there are periods in that build process where the CPU is not very busy. So during the clone and

163
00:17:48,720 --> 00:17:55,760
during the documentation upload at the end, the CPU is effectively sitting idle. If we could have

164
00:17:55,760 --> 00:18:04,880
more virtual machines per node, we could even that CPU out significantly on the hosts and get more

165
00:18:04,880 --> 00:18:11,120
work done with the same amount of hardware, which would be something that we'd love to do. So I'm

166
00:18:11,120 --> 00:18:16,400
fairly confident the person responsible for that decision is not listening, but just in case they

167
00:18:16,400 --> 00:18:24,240
are. - Send us the secret user defaults command to disable that limit. - Or send us the secret user

168
00:18:24,240 --> 00:18:32,080
defaults command, yeah. I'm sure if you disable system integrity, whatever, you could probably

169
00:18:32,080 --> 00:18:38,560
find a way to make it work, but that is not what we're doing. We are faithfully following the

170
00:18:39,360 --> 00:18:49,280
license agreement that we agreed to. So the good news is that we've been doing

171
00:18:49,280 --> 00:18:57,440
quite a bit of testing with this system before we put it live. And we ran a lot of the early Swift6,

172
00:18:57,440 --> 00:19:04,560
ready for Swift6 build queues with this cluster before we switched over our production workload

173
00:19:04,560 --> 00:19:12,080
onto that as well. And it has just been an absolute dream to work with. There was a little

174
00:19:12,080 --> 00:19:16,400
bit of software development that we needed to do to get it all working. We need to

175
00:19:16,400 --> 00:19:25,920
write a fairly small piece of software that orchestrates the cluster, basically. So it reads

176
00:19:27,040 --> 00:19:35,440
incoming jobs that it needs to process, decides which VM type to spawn, spawns the VM,

177
00:19:35,440 --> 00:19:40,640
SSHs into it, executes the build commands, and then at the end shuts that machine down

178
00:19:40,640 --> 00:19:49,760
and reallocates the resources back to the cluster. But apart from that, it's been fairly

179
00:19:49,760 --> 00:19:54,960
easy. I don't think we needed in the end any changes to our builder tool. Is that right,

180
00:19:54,960 --> 00:20:00,960
Sven? No, in fact, what made it a bit more complicated, I think, was that for a time,

181
00:20:00,960 --> 00:20:08,000
we actually ran both because we always had builds coming in. So it was really hard. It wasn't really

182
00:20:08,000 --> 00:20:12,560
practical to say, well, we're not going to process builds for a few days while we sort this out.

183
00:20:12,560 --> 00:20:17,840
So the way we set this up, that we actually ran both systems at the same time. And you can imagine

184
00:20:18,640 --> 00:20:25,680
that's a bit more complicated because it's a very different way of bringing up jobs,

185
00:20:25,680 --> 00:20:30,320
because one machine has a GitLab runner permanently running that picks up the jobs,

186
00:20:30,320 --> 00:20:35,280
and the runner knows exactly what machine it's on. In the other case, the machine is ephemeral,

187
00:20:35,280 --> 00:20:39,600
so there's nothing running to pick up jobs. So something else needs to do that. And we sort of

188
00:20:39,600 --> 00:20:47,680
had to move the logic that sits in the runner into this orchestrator and driver. And at the

189
00:20:47,680 --> 00:20:53,760
same time, not pull out the old one. So we needed to do both things at the same time while we were

190
00:20:53,760 --> 00:20:58,320
transitioning over. And that was the fiddly bit that also worked out quite well. So after we

191
00:20:58,320 --> 00:21:06,480
figured out how to do that, that really allowed us to take our time in transitioning over and making

192
00:21:06,480 --> 00:21:12,240
sure it works as we expected. Because in a system like that, you don't really want to go back and

193
00:21:12,240 --> 00:21:18,160
forth, right? You don't want to transition too fast and then realize, "Whoa, whoa, whoa, hold on,

194
00:21:18,160 --> 00:21:23,760
this isn't actually working." And there were a couple of cases where it did not quite work out

195
00:21:23,760 --> 00:21:34,000
all right in our first attempt. And we needed to sort of stop processing for a bit and redo some

196
00:21:34,000 --> 00:21:39,760
things. This was mainly about our stuff where we didn't report the results back properly or the

197
00:21:39,760 --> 00:21:45,920
queues didn't see the build failure. So they thought that we're actually okay. And stuff like

198
00:21:45,920 --> 00:21:50,640
little fiddly bits that get wrong when you... I mean, everyone who's ever set up a CI system knows

199
00:21:50,640 --> 00:21:55,920
exactly what I'm talking about, right? You think you have it running, then you send the job to CI,

200
00:21:55,920 --> 00:21:59,520
everything's green. And then you look at the logs and you see, "Oh, it actually failed." And you

201
00:21:59,520 --> 00:22:06,800
didn't catch the last build result and that sort of stuff. And when you run lots of builds,

202
00:22:09,520 --> 00:22:12,800
you kind of don't want to get that wrong. And that was the fiddly part.

203
00:22:12,800 --> 00:22:19,680
- Not content with setting up our own CI for our tests, we decided to set up CI for the entire

204
00:22:19,680 --> 00:22:21,760
package ecosystem. - Yeah, well, actually, we're not,

205
00:22:21,760 --> 00:22:29,200
we're just running builds. I mean, we're never going to run tests. I'm going to say that here

206
00:22:29,200 --> 00:22:38,000
now, but just the builds is fun sometimes. - Exactly. So I think it's

207
00:22:38,080 --> 00:22:51,760
a great upgrade of our both capability and also the kind of stability and isolation of our build

208
00:22:51,760 --> 00:23:01,200
environment. I sleep completely at ease these days with knowing that there's zero risk of

209
00:23:01,200 --> 00:23:05,040
waking up to a build machine which has been compromised.

210
00:23:05,040 --> 00:23:11,280
- Yeah, that's actually a good final point maybe to raise because one of the issues we did

211
00:23:11,280 --> 00:23:17,920
occasionally see that was a problem with the old system was when one of our builders fell over and

212
00:23:17,920 --> 00:23:22,480
it was a specific Swift version that was only served by one builder. It could actually happen

213
00:23:22,480 --> 00:23:27,680
that our queue filled up with those builds and then we wouldn't actually continue processing.

214
00:23:27,680 --> 00:23:34,160
And that's actually something that can't happen anymore. And that's, I think, the key thing that

215
00:23:34,160 --> 00:23:37,920
we're actually gaining operationally apart from all the maintenance stuff and debugging

216
00:23:37,920 --> 00:23:44,000
that really, you know, a couple of times caused trouble with the old system.

217
00:23:44,000 --> 00:23:49,760
- So we'd like to say a huge thank you to Max Stadium. They have been

218
00:23:49,760 --> 00:23:58,080
supporting this project since the beginning. And if they have a very generous open source

219
00:23:58,880 --> 00:24:04,880
program actually, which is available to any open source project, which is if you require a

220
00:24:04,880 --> 00:24:11,200
Mac mini or something like that for your project, if GitHub Actions are no longer

221
00:24:11,200 --> 00:24:20,160
cutting it for what you need to do in terms of CI, they offer an open source program to provide

222
00:24:20,160 --> 00:24:26,480
that kind of resource for free. And we'll put a link in the show notes to that. But also, obviously,

223
00:24:27,520 --> 00:24:34,160
it's a little bit of a different situation having a few Mac minis to eight Mac studios,

224
00:24:34,160 --> 00:24:43,040
but they continue to support us by making this possible. So, you know, not to go into the full

225
00:24:43,040 --> 00:24:51,040
details of it, but this would not be possible without their support. So thank you so much for

226
00:24:52,080 --> 00:24:58,480
everything you've done for us. And more importantly than the supply of the resources is

227
00:24:58,480 --> 00:25:04,960
every single conversation we've had with them has been met with, well, let's figure out a way to do

228
00:25:04,960 --> 00:25:12,800
this. So when we started talking about ephemeral builds, it wasn't a case of, well, are we actually

229
00:25:12,800 --> 00:25:21,360
going to be able to keep this within a sensible budget, but just how are we going to do it? Is it

230
00:25:21,360 --> 00:25:25,920
going to be the best solution? And I've kind of worked from there. So I can't say enough good

231
00:25:25,920 --> 00:25:35,120
stuff about actually both Mac Stadium and Azure, they are both exceptionally accommodating with

232
00:25:35,120 --> 00:25:40,320
every request that we've made to them. Yeah, absolutely. Huge, huge. Thank you.

233
00:25:40,320 --> 00:25:42,000
All right.

234
00:25:42,000 --> 00:25:45,920
Right. There's another piece of news while we were talking about the build system. Maybe that's

235
00:25:45,920 --> 00:25:54,080
something worth highlighting right now. Because this week we crossed a nice threshold and that's

236
00:25:54,080 --> 00:26:01,120
10% of all packages are now opting into host documentation on the Swift package index. And I,

237
00:26:01,120 --> 00:26:06,720
I was sort of tracking this number. So I saw it coming. There's been a really interesting

238
00:26:06,720 --> 00:26:13,200
increase recently in a number of packages opting in like new packages, the ratio is quite high.

239
00:26:14,400 --> 00:26:20,800
Well, higher than 10%. I mean, that's obviously how we're catching up starting from zero. But I

240
00:26:20,800 --> 00:26:28,080
sort of was thinking back when we rolled out documentation hosting, I thought, well, you know,

241
00:26:28,080 --> 00:26:32,480
getting a couple of percent would be nice, you know, like maybe a couple of hundred packages.

242
00:26:32,480 --> 00:26:39,120
And now we're, we've crossed the 750 mark and the 10% mark. That's actually quite extraordinary how

243
00:26:39,120 --> 00:26:45,280
many authors are actively opting in because this is not something we are doing right. Every package

244
00:26:45,280 --> 00:26:51,040
author needs to add this SPI.yaml file to their repository. I mean, it's not a huge change,

245
00:26:51,040 --> 00:26:54,400
but it is something you actually need to be doing and be looking at.

246
00:26:54,400 --> 00:26:56,560
It takes a git commit.

247
00:26:56,560 --> 00:26:59,920
Yeah. That's the thing. Yeah.

248
00:26:59,920 --> 00:27:06,000
Anything that requires any kind of git commit is asking the package author to do something

249
00:27:06,000 --> 00:27:12,640
that they probably weren't expecting to do. So no, it is not an onerous procedure by any means,

250
00:27:12,640 --> 00:27:18,400
but it is something that takes action rather than a passive process.

251
00:27:18,400 --> 00:27:20,160
Yeah. Yeah, absolutely.

252
00:27:20,160 --> 00:27:24,160
One thing that I was curious about when you told me this stat during the week was

253
00:27:24,160 --> 00:27:32,240
whether it has changed recently and in terms of, because obviously when we first launched

254
00:27:32,240 --> 00:27:37,600
the package index, we didn't have documentation hosting. And so I have a little quiz question

255
00:27:37,600 --> 00:27:47,120
for you based on the fact of we added into our package, our add a package process, a little

256
00:27:47,120 --> 00:27:52,480
call to action at the end, which is to let package authors know that they can host their documentation

257
00:27:52,480 --> 00:27:57,760
with us and link to the documentation that we have on how to do that. And so what I did is I

258
00:27:57,760 --> 00:28:06,640
did a little filtered query to say what the percentage of packages that have adopted our

259
00:28:06,640 --> 00:28:13,520
documentation system in the last year was. What would you say the percentage of packages, given

260
00:28:13,520 --> 00:28:18,000
it's 10% overall, if it's packaged in the last year, what do you think we're at?

261
00:28:18,000 --> 00:28:26,000
Well, I'm slightly cheating because I do track the number of new packages, you know, that number.

262
00:28:26,000 --> 00:28:30,160
So I, but you know, I, that's this from memory, I'd say maybe 25%.

263
00:28:30,160 --> 00:28:38,640
No, it's not quite that. It's 16, just over 16%. There are 306 packages in the last year

264
00:28:38,640 --> 00:28:46,880
that have added documentation as part of it. Although that number is slightly skewed,

265
00:28:46,880 --> 00:28:53,840
I think skewed lower because of the way that our rename process works. So we track when people

266
00:28:54,480 --> 00:29:01,360
rename their packages within our organization. And we also track moving packages from one

267
00:29:01,360 --> 00:29:10,400
organization to another on GitHub. And every time we detect a rename, that actually shows up in our

268
00:29:10,400 --> 00:29:17,520
kind of stats as a removal and an addition of a package. And so there are potentially some

269
00:29:17,520 --> 00:29:22,080
double counted packages there because of that process. But I don't think that would,

270
00:29:22,080 --> 00:29:24,880
I don't think it's enough to be statistically significant.

271
00:29:24,880 --> 00:29:30,640
Yeah, I'm certainly probably biased because just the recent, like recent weeks, it was 30%.

272
00:29:30,640 --> 00:29:35,920
It's been really high, the ratio of adoption. I'm not sure why that is. Maybe it's

273
00:29:35,920 --> 00:29:44,560
WWDC was a documentation thing or something, or maybe I don't know, but it's been noticeable,

274
00:29:44,560 --> 00:29:47,120
the uptick in the ratio.

275
00:29:47,120 --> 00:29:53,360
I think it's, I love the fact that we're so high on hosted documentation. I think that's,

276
00:29:53,360 --> 00:30:00,080
it's great to see. And it's great to see so many package authors putting the time and effort into

277
00:30:00,080 --> 00:30:01,680
creating documented packages.

278
00:30:01,680 --> 00:30:03,200
Yeah, absolutely. Yeah.

279
00:30:03,200 --> 00:30:06,320
Let's do some package recommendations, shall we?

280
00:30:06,320 --> 00:30:06,800
Let's go.

281
00:30:06,800 --> 00:30:08,320
Do you want to start us off?

282
00:30:08,320 --> 00:30:16,320
All right, I shall do so. My first package is a package I absolutely love. It's called

283
00:30:16,320 --> 00:30:24,880
Swift Testing Revolutionary by Koki Miki. And I just love this. When I first saw Swift Testing,

284
00:30:24,880 --> 00:30:31,600
I was really excited about this Swift Testing package. And we've now seen the introduction

285
00:30:31,600 --> 00:30:37,680
at WWDC. I just love testing. I mean, I spend a lot of time in tests, so anything in that area

286
00:30:37,680 --> 00:30:43,920
really gets me excited. But I also knew looking at our test suite, just in the main project,

287
00:30:43,920 --> 00:30:51,040
we have 766 tests. And obviously, that's just tests. That's not even just assertions. That's

288
00:30:51,040 --> 00:30:55,600
way more. I thought, well, that's going to be a while until we actually use that extensively,

289
00:30:55,600 --> 00:31:02,240
right? Because you're not going to dive in and adopt that, cross the board and make all those

290
00:31:02,240 --> 00:31:08,800
changes. But then I saw this amazing tool last week. It was announced on the Swift forums.

291
00:31:10,000 --> 00:31:16,640
And it's a tool, like a build tool that you can add to your package, like the new build tool thing

292
00:31:16,640 --> 00:31:22,960
that you can trigger in Xcode or via the Swift Package Manager. Or you can use it as a command

293
00:31:22,960 --> 00:31:28,560
line utility. And what it does, it rewrites your tests to the new Swift testing syntax.

294
00:31:28,560 --> 00:31:36,480
And what that means is it adds the @Suite annotation, converts your test class to a struct,

295
00:31:36,480 --> 00:31:42,720
or optionally leaves it as a class. You can configure that. It adds the @Test annotations

296
00:31:42,720 --> 00:31:50,800
to each of your test functions. And it converts your XCT test assert calls to the new #expect

297
00:31:50,800 --> 00:32:00,480
expression. And that is an amazing time saver. And I actually tried this out in our repository

298
00:32:00,480 --> 00:32:07,680
with the 766 tests. So this is like, it's so fast. At first I thought, well, it probably didn't do

299
00:32:07,680 --> 00:32:13,440
anything because it just finished in like less than half a second. And it rewrote all the tests.

300
00:32:13,440 --> 00:32:20,960
Now in our test suite, it isn't working perfectly. And I'll explain why in a second. But in

301
00:32:20,960 --> 00:32:28,160
a plain case where we were using an XCTest case as the base class, it converted the tests perfectly.

302
00:32:28,160 --> 00:32:33,360
And they ran and they passed. And it was excellent. It was just no notes. It just worked.

303
00:32:33,360 --> 00:32:40,240
The problem it has is with cases where we use a different base class. And that's where we have

304
00:32:40,240 --> 00:32:47,360
snapshot tests or database tests where we inherit from our own class and then use

305
00:32:47,360 --> 00:32:53,040
objects of that class in the tests. And because it converts that, and I didn't fiddle with any,

306
00:32:53,600 --> 00:32:58,800
I just used the default setting and converted it to a struct. So it converted it to a struct.

307
00:32:58,800 --> 00:33:04,640
And then obviously that lost all the inheritance and the tests didn't compile because they didn't

308
00:33:04,640 --> 00:33:10,160
know about the DB or the app properties. It just didn't exist on the struct. But that's

309
00:33:10,160 --> 00:33:17,600
really simple to fix. Perhaps even just by using that other mechanism and making it a class with

310
00:33:17,600 --> 00:33:25,360
an absolute annotation or just fixing it up. I mean, that's trivial. The main thing is that

311
00:33:25,360 --> 00:33:31,920
rewrites all the tests and adds the @test annotation and it converts all your asserts.

312
00:33:31,920 --> 00:33:37,600
And that's the big thing because that's hundreds and hundreds of lines of changes

313
00:33:37,600 --> 00:33:44,480
that we just save. It's amazing. Yeah. This is not a tool that you're going to need to run

314
00:33:44,480 --> 00:33:49,280
as part of a build process or anything that's going to need to be, that the output is going

315
00:33:49,280 --> 00:33:55,760
to need to be perfect for fixing up a few edge cases after the tool has run. It's a perfectly

316
00:33:55,760 --> 00:34:00,080
acceptable way of running this tool. And because once you've run it, you've run it and that's it,

317
00:34:00,080 --> 00:34:07,840
it's converted, it's done. So yeah, what a great tool. I hadn't seen this. So that was fascinating

318
00:34:07,840 --> 00:34:12,640
hearing about that. Great. Yeah. It's really nice. And obviously you can do it file by file. So it's

319
00:34:12,640 --> 00:34:18,720
like, I'm really looking forward to this because I really want to use some of the new stuff.

320
00:34:18,720 --> 00:34:26,400
And obviously that's all predicated by actually moving over. And if this allows us to move us

321
00:34:26,400 --> 00:34:33,040
over fast, that's super exciting because it'll open up Swift testing much, much sooner than I

322
00:34:33,040 --> 00:34:38,480
would have thought it would. I must admit, I had wondered whether we would ever actually migrate

323
00:34:38,480 --> 00:34:45,440
to it because of the fact that we have so many tests already. I thought maybe we would approach

324
00:34:45,440 --> 00:34:50,000
it in the case of, well, if you're writing new tests, then you write them in Swift testing.

325
00:34:50,000 --> 00:34:55,440
But I'm very happy to hear that that won't be necessary. Yeah. Well, I hope we'll see what

326
00:34:55,440 --> 00:35:02,400
happens, but I'm really, just this short test showed me it's probably quite viable. I'm not,

327
00:35:03,520 --> 00:35:08,800
yeah, I'm just really hopeful. Did you check that the result of the conversion process was not to

328
00:35:08,800 --> 00:35:17,120
XCT assert true to make sure all the tests pass? No, it's actually quite remarkable because like,

329
00:35:17,120 --> 00:35:21,840
yeah, I know you're joking, but like, for instance, it rewrites an XCTest assert where

330
00:35:21,840 --> 00:35:31,360
equals where you have A comma B, it converts that into a hash expect A equals equals B. So it, I

331
00:35:31,360 --> 00:35:37,280
mean, obviously uses Swift syntax to actually understand your test syntax and intelligently

332
00:35:37,280 --> 00:35:44,240
rewrites that. So you get a lot of mileage out of this. Just if all it did was rewrite the

333
00:35:44,240 --> 00:35:49,200
assert macros, the exert, you know, well, they're actually macros in the

334
00:35:49,200 --> 00:35:55,120
original Objective-C, I think in Swift their functions, but these, I still, in my head,

335
00:35:55,120 --> 00:36:02,160
I still think of them like as macros. They, it's just, if it just rewrote those, that would already

336
00:36:02,160 --> 00:36:09,360
be a huge time-saver because that's obviously the most lines in that diff is the asserts and then

337
00:36:09,360 --> 00:36:14,960
tests, you know, the individual tests. And then I think we have like maybe 15

338
00:36:14,960 --> 00:36:22,400
test classes. So if, even if it didn't, those that would be trivial, right? 15 things you can,

339
00:36:22,400 --> 00:36:26,880
you can manually convert it's the others that are important and those, those seem to be coming

340
00:36:26,880 --> 00:36:35,200
across really well. Right. So yeah, big thumbs up. So from a brand new package like that one

341
00:36:35,200 --> 00:36:40,720
to my first recommendation this week, which is to, for a package that has been around for seven

342
00:36:40,720 --> 00:36:50,800
years. And it's actually a package we use in the Swift package index. And it's by far not a new

343
00:36:50,800 --> 00:36:58,080
package, but it is one that received a major version upgrade this week. And it is Soto by,

344
00:36:58,080 --> 00:37:05,040
well, the Soto project is the official organization name, but it's primarily written by Adam Fowler.

345
00:37:05,040 --> 00:37:12,400
And I was looking through packages and there were actually a huge number of new packages this week.

346
00:37:13,200 --> 00:37:23,760
But this one, the major version struck me because it is a full conversion to away from event loops

347
00:37:23,760 --> 00:37:32,160
and into a Swift concurrency. So that's a great step forward for the package. But I should also,

348
00:37:32,160 --> 00:37:34,960
I should also explain what the package does for those people not familiar with it.

349
00:37:36,480 --> 00:37:48,000
It is a Swift language SDK for all of the Amazon web services APIs. So Amazon are constantly adding

350
00:37:48,000 --> 00:37:55,520
and changing their APIs, I'm sure. And this effectively is guaranteed to always be up to

351
00:37:55,520 --> 00:38:00,480
date with those because it is kind of generated from their API definitions. So this is very

352
00:38:00,480 --> 00:38:05,600
unlikely to be used from like an iPhone app or anything like that, or a watch OS app. I don't,

353
00:38:05,600 --> 00:38:11,360
I don't start up EC2 instances from my watch very often. But it's certainly if you're doing

354
00:38:11,360 --> 00:38:18,000
any kind of server side Swift, then this will likely be already in your project. And so it's

355
00:38:18,000 --> 00:38:23,280
worth a note when it does something significant, like upgrade itself completely from event loops to

356
00:38:23,280 --> 00:38:30,320
Swift concurrency. And I just thought that I looked through, I was actually kind of surprised

357
00:38:30,320 --> 00:38:37,280
that in the 40 something episodes of this podcast so far that we hadn't yet talked about Soton.

358
00:38:37,280 --> 00:38:38,800
And I thought it was time. Oh, we haven't.

359
00:38:38,800 --> 00:38:44,640
That's, that's interesting. I checked the show notes and it's not there yet. Have you

360
00:38:44,640 --> 00:38:48,800
also checked its old name because there was a rename it was called something AWS

361
00:38:48,800 --> 00:38:55,760
kit or something before. Oh, I don't know whether I did. I don't quite recall its original name,

362
00:38:55,760 --> 00:39:04,400
but obviously it was called something AWS and that that needed to be changed when AWS introduced

363
00:39:04,400 --> 00:39:09,840
their own. We have nothing in our, in our list of packages that we've talked about on the podcast

364
00:39:09,840 --> 00:39:16,080
that mentions either AWS or Soto. So remarkably I don't know how we haven't talked about it because

365
00:39:16,080 --> 00:39:20,400
it is, it is one of those packages that I thought would definitely be on this list, but it's, but

366
00:39:20,400 --> 00:39:26,800
it's not anyway, worth a mention Soto by Adam Fowler for all of your AWS needs.

367
00:39:26,800 --> 00:39:36,560
So my second pick is called Swift sessions by Alessio Rubicini. And that's also a package I

368
00:39:36,560 --> 00:39:44,640
saw on the Swift forums. And Alessio also points to an introductory blog post, which explains this

369
00:39:44,640 --> 00:39:50,960
package in a little more detail. And there was a really nice line in that, in that blog post,

370
00:39:50,960 --> 00:39:55,840
it says, so this package is about Swift sessions. It's about session, so-called session types,

371
00:39:55,840 --> 00:40:03,920
which is apparently like a computer science concept. And he writes, this is a concept.

372
00:40:03,920 --> 00:40:09,280
If you've never heard about session types, that's normal. This is a concept born and explored

373
00:40:09,840 --> 00:40:19,200
in recent decades. This is where I expected like weeks or months, but he says decades. So

374
00:40:19,200 --> 00:40:23,600
we, I certainly missed it in recent decades. I'd never heard about session types.

375
00:40:23,600 --> 00:40:27,040
It's new to me too.

376
00:40:27,040 --> 00:40:34,480
Well, there you go. We, we kind of missed it in recent decades. The, the blog post does a really

377
00:40:34,480 --> 00:40:41,120
nice job explaining what it is. Nonetheless, it is, it seems like a complicated topic, but in a

378
00:40:41,120 --> 00:40:49,680
nutshell, what it does, it is using type checking to, to assert or implement a message exchange and

379
00:40:49,680 --> 00:40:56,160
make sure that the bits line up like the parts line up. So imagine you have a side A, and this

380
00:40:56,160 --> 00:41:01,040
is sort of taken from the blog post. You have a side A that sends an integer across the wire,

381
00:41:01,040 --> 00:41:09,840
then expects to get a bool back, and then the communication ends. So that's side A, sending int,

382
00:41:09,840 --> 00:41:18,240
getting bool, and then end. And side B has, has the, the message receiving an int,

383
00:41:18,240 --> 00:41:22,960
sending a bool, and then it ends. And you can see how these line up, right? Sort of like,

384
00:41:22,960 --> 00:41:27,440
you know, imagine like saw teeth in a, in a gear cogs and they sort of, you know, you have the

385
00:41:27,440 --> 00:41:32,880
exact right alignment of sending, receiving int, sending and receiving bool, and then

386
00:41:32,880 --> 00:41:38,160
both expect to end. And this is something that, that this package allows you to encode in the

387
00:41:38,160 --> 00:41:45,520
type system. So at compile time, it'll be ensured that your messages line up and, and, you know,

388
00:41:45,520 --> 00:41:50,800
the, the orders also, and not just the types line up, but the, the order, the sequence order of your

389
00:41:50,800 --> 00:41:57,040
message exchange is, is asserted at compile time. And that, that seems like a really nice

390
00:41:57,040 --> 00:42:05,360
guarantee to have, you know, and this package makes that possible. One note, if you use this,

391
00:42:05,360 --> 00:42:09,920
you, you probably want to make heavy use of type aliases and use type inference, because

392
00:42:09,920 --> 00:42:15,760
otherwise you will get hurt by all the pointy angle brackets in the type signatures. It has lots

393
00:42:15,760 --> 00:42:22,480
of, lots of those going on, as you might imagine. But it's one of these cases where the type system

394
00:42:22,480 --> 00:42:29,200
really opens up opportunities or possibilities to use the compiler to check things for you that,

395
00:42:29,200 --> 00:42:34,480
that weren't possible before. And I find that really interesting to see these kind of new

396
00:42:34,480 --> 00:42:39,120
packages pop up that, that make use of these things. That's great. So there you go. That's

397
00:42:39,120 --> 00:42:47,760
Swift Sessions by Alessio Rubicini. My final package for this time is a package called Tabula

398
00:42:48,320 --> 00:42:57,440
by António Pedro Marques. And this is, well, it's a package. Let me tell you the stuff. Let me start

399
00:42:57,440 --> 00:43:06,080
with what the package does, and then I'll tell you why I picked it. The package is a spreadsheet

400
00:43:06,080 --> 00:43:14,160
reader and writer. So you can combine it with another package called CoreXLSX by a core office

401
00:43:14,160 --> 00:43:18,000
organization, which actually looks from the author information, it looks like it was written by

402
00:43:18,000 --> 00:43:25,600
Max Desiatov, who is now at Apple and who, but before that had his fingers in all sorts of open

403
00:43:25,600 --> 00:43:38,640
source packages. And the combination of them allow you to read and write data from spreadsheets.

404
00:43:39,920 --> 00:43:45,040
So that in itself is the kind of thing, this is, you know, it's fairly niche

405
00:43:45,040 --> 00:43:48,480
things I want to do. Not every application is going to want to read and write

406
00:43:48,480 --> 00:43:58,000
spreadsheet files or Excel files. But it reminded me of a project that is both probably the very

407
00:43:58,000 --> 00:44:03,760
worst code I ever wrote as a developer, but also in its own way, the best code that I ever wrote

408
00:44:03,760 --> 00:44:14,560
as a developer. So this is way back in the 16-bit era when I was working for a software company that

409
00:44:14,560 --> 00:44:19,760
wrote HR software, so job evaluation and kind of pay modeling software and that kind of thing.

410
00:44:19,760 --> 00:44:28,560
And we had this job evaluation system where you would put definitions of roles into this system.

411
00:44:28,560 --> 00:44:36,880
And then as a team of management consultants that we had in the company would work out within that

412
00:44:36,880 --> 00:44:45,280
business, what were the important aspects of that role that made it more responsible and made it

413
00:44:45,280 --> 00:44:53,600
effectively a ranking of jobs from low to high across an organization. And it was used in lots

414
00:44:53,600 --> 00:45:00,320
of equal pay disputes and things like that, where you could prove that the job requires this rather

415
00:45:00,320 --> 00:45:07,120
than the person doing it requiring something. So it was a great piece of software, but the

416
00:45:07,120 --> 00:45:13,520
management consultants who came up with the rules on a company by company basis determined what was

417
00:45:13,520 --> 00:45:20,800
important in that company. What they did was they loved using Excel spreadsheets to basically make

418
00:45:20,800 --> 00:45:27,760
these rules. And what we would then have to do is take those Excel spreadsheets and convert them into

419
00:45:27,760 --> 00:45:36,160
code. And that was okay. I mean, it was never terrible work, but it was fairly tedious work.

420
00:45:36,160 --> 00:45:41,680
And it was also prone to mistakes. So when you're reading from an Excel spreadsheet with an

421
00:45:41,680 --> 00:45:50,640
extremely complicated formula behind it, the potential for errors there is very high.

422
00:45:50,640 --> 00:45:55,440
So we did lots of testing to make sure we got it right and that kind of stuff. And

423
00:45:55,440 --> 00:46:03,520
when we were moving this to work on the web, because originally this was just desktop software,

424
00:46:04,720 --> 00:46:11,600
we came up with this idea that actually maybe we should just open the Excel spreadsheets,

425
00:46:11,600 --> 00:46:18,800
poke a value in, let Excel do the calculation and read the value out of the other side of it

426
00:46:18,800 --> 00:46:24,720
every time we needed to do these calculations. So one of the first pieces of web software that

427
00:46:24,720 --> 00:46:36,080
I ever wrote was a 16-bit Visual Basic COM component, which was a component object model,

428
00:46:36,080 --> 00:46:46,080
I think it was, that allowed Visual Basic to interact with ASP, not ASP.NET, just ASP,

429
00:46:46,080 --> 00:46:51,360
which was the original Microsoft scripting language, very primitive web scripting language

430
00:46:51,360 --> 00:46:58,800
that was, but it could call out to a COM component that then executed a command line

431
00:46:58,800 --> 00:47:07,840
16-bit Delphi application that could read and write the Excel spreadsheet. So it would poke

432
00:47:07,840 --> 00:47:12,960
a number into the Excel spreadsheet, read the number out back out of the Excel spreadsheet and

433
00:47:12,960 --> 00:47:18,080
leave a file on disk that the COM component then picked up and sent back to the database and stored

434
00:47:18,080 --> 00:47:24,400
in the database. So you too can build your own Excel Rube Goldberg machine with Tabular.

435
00:47:24,400 --> 00:47:26,640
- And that's how it was done back in those days.

436
00:47:26,640 --> 00:47:35,360
- I mean, that was it. And what was incredible was you'd look at the processes running on this

437
00:47:35,360 --> 00:47:42,240
web server and to see, you know, 14 different copies of Excel all in memory doing calculations

438
00:47:42,960 --> 00:47:49,600
as the web server fielded requests. And the reason I say it was both the worst,

439
00:47:49,600 --> 00:47:52,640
I think it's quite obvious why I'm saying it's the worst bit of software I ever wrote.

440
00:47:52,640 --> 00:48:00,000
But the reason it was the best bit of software I ever wrote was because it worked flawlessly

441
00:48:00,000 --> 00:48:08,720
for years and there was never a problem with it. It never got it wrong, it just worked perfectly.

442
00:48:08,720 --> 00:48:11,840
- Exactly.

443
00:48:11,840 --> 00:48:13,920
- And we can't ask for much more than that, right?

444
00:48:13,920 --> 00:48:19,200
- It is sometimes extraordinary to what lengths organizations go to, especially banks. I worked

445
00:48:19,200 --> 00:48:28,240
at a few banks. They'll get a system running once and then they'll go to extraordinary lengths to

446
00:48:28,240 --> 00:48:33,760
keep that system running, no matter the cost. They'll just build anything around it to just

447
00:48:33,760 --> 00:48:40,480
keep that one system going that managed to get this thing running in the first place and just

448
00:48:40,480 --> 00:48:43,360
keep chugging away with it. It's sometimes quite remarkable.

449
00:48:43,360 --> 00:48:50,560
- Exactly. But yeah, I mean, it was great. And who knows, maybe it's still running today.

450
00:48:50,560 --> 00:48:56,560
I don't think it is, but who knows? So I think we should probably wrap it up there, I think.

451
00:48:56,560 --> 00:49:03,200
And we will be back in three weeks with another episode with some more packages for you to have

452
00:49:03,200 --> 00:49:09,840
a look at and news from the Swift Package Index. But until then, I will say see you in a few weeks.

453
00:49:09,840 --> 00:49:12,840
See you next time. Bye bye.