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.