WEBVTT

00:00.000 --> 00:09.400
Thank you for being still here at this time of the day.

00:09.400 --> 00:16.520
We are welcoming time, had a day, for implementing stream spec in server web engine.

00:16.520 --> 00:18.320
Yes, thank you.

00:18.320 --> 00:20.320
Thank you everyone.

00:20.320 --> 00:21.320
Thank you for having me.

00:21.320 --> 00:26.120
I'm really happy to be here today to talk about the implementation of Steve Speck in

00:26.120 --> 00:34.120
server, before we start, about me, so I'm a software engineer from Netherlands and

00:34.120 --> 00:37.080
basically focus on embedded systems.

00:37.080 --> 00:42.000
And my free time, mostly weekend, and after noon, I will contribute to server, across the

00:42.000 --> 00:47.360
engine, team 95, you can follow me team 95 online.

00:47.360 --> 00:51.880
Yeah, so I want to talk about server, I think I'll go already thought about server

00:51.880 --> 00:52.880
with morning.

00:52.880 --> 00:55.800
I'll drive in directly in the implementation.

00:55.800 --> 01:02.520
So as we know, streams are quite important in a web engine, basically they are used almost everywhere,

01:02.520 --> 01:09.480
fetched, fetched body, upload, download, compress, and decompress, APIs, and basically

01:09.480 --> 01:13.880
if you have a broken stream implementation in your web engine, you have a missing part

01:13.880 --> 01:16.000
if you're working in.

01:16.000 --> 01:19.920
What was the status of the stream implementation in server?

01:19.920 --> 01:28.000
So server will use modules, which is a rust binding for spider monkey, and spider monkey

01:28.000 --> 01:33.640
had its own implementation of stream implemented in engine, because we were creating this

01:33.640 --> 01:39.400
binding, or we were also creating the binding of these stream implementation from the engine.

01:39.400 --> 01:45.800
And specific spider monkey version, these built in implementation, they were removed from

01:45.800 --> 01:48.240
the engine, but they were moved to the Firefox.

01:48.240 --> 01:53.280
So basically you can browse them in Firefox, Firefox, and Cutsers.

01:53.280 --> 01:59.760
That created an issue for server, because basically if we upgrade to the new version, we

01:59.760 --> 02:06.520
don't have the stream implementation, it will break our fetch implementation at whole,

02:06.520 --> 02:09.440
the WPT test will go down.

02:09.440 --> 02:16.040
So we were in a situation where we cannot update without compromising.

02:16.040 --> 02:18.800
So we were trying to find a short-term solution.

02:18.800 --> 02:24.440
Basically the short-term solution is to update spider monkey, but also create a patch, which

02:24.440 --> 02:30.240
will bring the deleted code from spider monkey, deleted code, or removed code, we're talking

02:30.240 --> 02:32.680
about this stream implementation.

02:32.680 --> 02:38.720
We know this is working, but basically it's not a long-term solution, what if we want

02:38.720 --> 02:45.360
to have a spec change or want to add a new one to fix something in stream implementation,

02:45.360 --> 02:46.840
this will be really hard.

02:46.840 --> 02:52.680
So the long-term solution is basically, basically re-implement in the stream implementation

02:52.680 --> 02:57.440
stream spec inside the server in Rust.

02:57.440 --> 03:02.280
And like this, we can basically have a spec driven stream implementation in Rust.

03:02.280 --> 03:08.280
We can follow on the bug, and we can also upgrade to the spider monkey version freely.

03:08.280 --> 03:13.160
To do this, so the implementation in the server, even though it was using spider monkey,

03:13.160 --> 03:20.040
but it was not fully implemented, it was only implemented, so fetch can work properly.

03:20.040 --> 03:27.560
Which means it was only implemented, readable stream, default controller, and default reader.

03:27.560 --> 03:34.640
To do this, we started the work where we identified what are the needed features to at least

03:34.640 --> 03:44.080
bring WPT test to the state where it was using the built-in spider monkey stream implementation.

03:44.080 --> 03:51.680
So we created, we could not do like a major PR for the server, so we created like an intermediate

03:51.680 --> 03:57.640
branch, and we started making like small PRs to build the stream implementation step by step.

03:57.640 --> 04:04.480
And when we were in the state where we are reaching the same amount of WPT test,

04:04.480 --> 04:10.600
we were passing before the in the built-in spider monkey implementation, we made the PR for

04:10.600 --> 04:17.080
server, which implemented readable stream, and in Rust, with the default controller and

04:17.080 --> 04:21.800
default reader.

04:21.800 --> 04:32.520
And of course, we were able to move the patch that we introduced for MOSJS, the patch that

04:32.520 --> 04:38.280
brings the delete code from spider monkey, and we can upgrade the failure now.

04:38.280 --> 04:45.720
So basically, this is the patch where, so basically in the past implementation, you will see

04:45.800 --> 04:51.240
function like read the chunk, which is a function to read the stream, it was using the direct

04:51.240 --> 04:59.480
code from spider monkey, and this is literally like an ff and binding through the engine directly,

04:59.480 --> 05:08.120
but we moved more like to Rust implementation without having this engine called directly in the

05:08.200 --> 05:17.800
server script, and we rely on the engine for handling the values of the object of the

05:17.800 --> 05:22.440
JavaScript object, because it's the need to communicate between two words. The good thing about

05:22.440 --> 05:30.680
this implementation is like it's following the spec, everything is documented, and yeah, it's easy for us.

05:31.000 --> 05:39.240
Okay, so since the implementation was only implemented for readable stream, default controller

05:39.240 --> 05:46.120
and default reader, when we wanted to implement a byte controller and be always a reader,

05:46.680 --> 05:50.360
we had an issue where we are still dealing with buffers, so we still need to call

05:50.360 --> 05:53.560
JavaScript engine functions. For example, if you have a buffer, you want to detach it,

05:53.560 --> 06:00.280
you still need to call detach function from the JavaScript engine, and we didn't want to get back

06:00.360 --> 06:06.040
to the same situation where we have JavaScript calls inside JavaScript, so we started by creating

06:06.040 --> 06:13.720
abstraction, we called the buffer source, which is literally a spec driven, this buffer source

06:13.720 --> 06:22.600
is the abstraction where we have all these JavaScript engine calls, and from the service script,

06:22.600 --> 06:27.400
you call these abstraction. And when we did this, we started noticing something really interesting,

06:28.200 --> 06:35.240
all these JavaScript engines, they share the same implementation, because they follow the TC39,

06:35.640 --> 06:41.640
and from this we started having idea, okay, if we started creating all these abstraction,

06:41.640 --> 06:47.080
can we reach the point where service script does not rely on the engine by itself, but

06:47.880 --> 06:54.200
rely on abstraction, the abstraction rely on the engine. And for example, we can see example rust V8,

06:55.000 --> 07:03.560
which is also the wrapper for V8, and rust testing function detach. But for buffer, it's easy,

07:03.560 --> 07:11.080
because it's like a direct, direct calls, but we still rely heavily on the spider monkeys,

07:11.080 --> 07:17.240
our server implementation, so creating abstraction will be a lot of work, and it will be like

07:17.240 --> 07:24.680
to take a lot of time, so I had a chat with one of the, one of the servo maintainer, and we agreed

07:24.680 --> 07:31.960
that this requires a lot of work, but it's a good sign. Okay, so since we have now an implementation

07:31.960 --> 07:38.280
of the stream in rust, it actually made it easy for us to implement the next step, or the missing

07:38.280 --> 07:44.440
part of the stream in servo, which will solve the most logical, the next part is to implement

07:44.440 --> 07:48.760
writeable stream, and when you have readable stream, writeable stream, you can implement transform

07:48.760 --> 07:53.880
stream. And that actually what we did, because we were just following the spec, now it's easy for us

07:53.880 --> 08:01.320
easy for the bug, because it just rust code, and then we implemented the rest of the spec.

08:03.960 --> 08:09.880
Yeah, so since we implemented writeable stream, we're also, sorry, it was simply quite

08:09.880 --> 08:17.800
a control signal, so we ended up also implementing a both controller, a both signal, and they are

08:17.800 --> 08:29.400
also all living in the rust in servo with the engine back in it. So what did this stream

08:29.400 --> 08:35.320
implementation that we did unlocked in servo? So we started not seeing that the community now,

08:35.400 --> 08:39.560
they're taking the stream implementation as a reference, and make it easy for them for them to

08:39.560 --> 08:46.040
implement older APIs. So for example, here, somebody is literally a took the stream implementation

08:46.040 --> 08:53.400
as a reference in implemented the compress and decompress API. Another team, another community member,

08:53.400 --> 08:59.480
also took the stream implementation as a reference, and implemented the decode test decode stream

08:59.480 --> 09:07.400
and test encode stream. So the implementation was a good reference. Yeah, the question is

09:07.400 --> 09:16.200
how does the stream implementation in servo on the WPT? So basically servo almost passed all the tests

09:16.200 --> 09:25.560
or all the stream tests, it's even sometimes surpass some other engines, but the butt is this,

09:25.560 --> 09:30.840
servo does not support shared worker, dedicated worker and service worker. So basically when you enable

09:30.840 --> 09:35.320
them all the stream implementation in that context they are failing of course, because we don't have

09:35.320 --> 09:41.800
the context, but the moment we will support this context, stream implementation is there, all the WPT test

09:41.800 --> 09:48.440
would be passing. The good news is that we are planning to start working on the workers in 2026 this year.

09:50.040 --> 09:54.840
Okay, so we talked about stream implementation, we talked about WPT, but what does it really mean

09:54.840 --> 10:00.920
for the for servo as a web engine? So basically because of this stream implementation about

10:00.920 --> 10:05.720
control or controller, we noticed that we were able example to make to have a functional

10:05.720 --> 10:15.000
functional GitHub, and we were able example to create a PR directly from for servo from using servo.

10:15.720 --> 10:26.120
And I think Rigo already showed it to, but basically we were able to run their servo and then

10:27.480 --> 10:36.280
you can go to PR's, you can review, you can also open. There's some missing functionalities,

10:36.280 --> 10:43.560
but I'm also logged in, so that was not possible before implementing these APRs.

10:44.520 --> 10:51.160
Back to the slide. Yeah, so there is another example, there is a community member

10:51.960 --> 10:57.720
that mentioned that example, this website, ShardGPT is not working, and with some investigation,

10:58.200 --> 11:04.520
and we found out that okay, the fetch uses stream, and one of the functions is

11:05.720 --> 11:12.600
when you try to clone the body of this fetch, it uses readable stream T with algorithms,

11:12.840 --> 11:18.120
and since it was not implemented, it was implemented not using this algorithm,

11:18.680 --> 11:23.960
and then when we used this spec, followed the spec correctly on using the stream,

11:23.960 --> 11:30.600
readable stream, inside the cloning of the body of the fetch, we were able to have at least

11:30.680 --> 11:40.040
ShardGPT website rendering, not rendering loading, of course, not fully working, but that was nice

11:40.760 --> 11:47.800
impact. Yeah, so we did a lot of work on stream, but there is still we still have some

11:48.600 --> 11:55.400
good start issues for people, if you want the work on them, we have a nice website called the

11:55.480 --> 12:04.760
StarSeries.org, you find some last issues there, join and reach out in servo Zulip Shard,

12:04.760 --> 12:12.520
if you want to have a chat, and check out the website. Yeah, so for the same implementation,

12:12.520 --> 12:17.880
it was quite a journey, and I would like to thank some, so I would like to thank an

12:17.880 --> 12:23.400
led foundation for supporting the project and believing in the project, also I would like to

12:23.400 --> 12:29.080
thank reviewer and maintainer, so George for helping us, understanding how inspired the monkey works,

12:29.080 --> 12:35.480
and how we can move from the build-in implementation to the own Rost servo implementation,

12:35.880 --> 12:40.200
also Gregory for working with me, he was supposed to be here, but he couldn't make it,

12:40.760 --> 12:47.640
and also the EGALATIM for also helping us support the project and reviewing our work.

12:48.600 --> 13:00.440
Yep, that's it, thank you. Thank you, we are ready at the time, so if you have questions,

13:01.000 --> 13:03.160
you can feed free to ask any question.

13:03.240 --> 13:17.880
Thank you for the presentation, I have a question about why what was different about streams

13:17.880 --> 13:25.160
that made it such that Mozilla implemented them in spider monkey at first versus in the browser

13:25.240 --> 13:34.840
engine. Yes, to be honest, I don't know exactly why they implemented in the browser,

13:35.400 --> 13:41.880
in the JavaScript engine itself, but I think the stream does not belong to the engine itself,

13:41.880 --> 13:47.080
but they are in like an API, also the engine, but why they did it, I'm not sure.

13:47.160 --> 13:52.840
Other questions?

14:01.160 --> 14:01.800
Don't be shy.

14:05.480 --> 14:11.720
Okay, so thank you then. Thank you so much and thank you for your presentation. Thank you.

