[haiku-development] Re: Plan for NetServices Kit (v2)

  • From: "Adrien Destugues" <pulkomandy@xxxxxxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Mon, 30 Aug 2021 07:09:00 +0000

30 août 2021 07:11 "Niels Sascha Reedijk" <niels.reedijk@xxxxxxxxx> a écrit:

Hi all,

This is going to be a long one and there is no easy TL;DR, so grab some 
coffee.

I have been looking at the state of the netservices and see how it can be 
improved. From my review,
I identified three main problems in the current API:
1. While the API is designed to be asynchronous, every request spins up in a 
separate thread, which
is an efficient way of using system resources.
2. The API design tries to be unified and therefore is quite prescriptive on 
what a request is and
how it works. This does not work well for all protocols, especially those 
that rely on keeping
server connections open (FTP, HTTP2 and 3).
3. The API implemented a callback interface, which executed callbacks within 
the context of the
dedicated request thread. This is problematic, as it does not impose any 
locking on the code that
is executed, and thus invites data races

In my opinion, if we want to continue to provide a Haiku-centric way of 
performing network requests
with multiple protocols, then we should (1) provide specific implementations 
for each of the
protocols (BHttpSession, BGopherSession, BFtpSession) and (2) an easy API to 
just 'get data at a
URL' for protocols that support an easy download (BUrlDownload).

Can you elaborate on how the B*Session classes are different from the B*Request 
and B*Result classes
which are already protocol specific? It does not seem to be such a big 
departure from the existing
design, which is in fact not as much prescriptive as you say. The only part 
that really needs to be
centralized in the current design is the BUrlProtocolRoster, which instanciates 
a B*Request from an
URL. We can then change the BUrlRequest API as needed, to fit more cases.

Our experience (even with HTTP) shows that there is a need for a B*Session 
class for each protocol,
since we want to do multiple requests within a single session/connection, let's 
add that. No problem
so far.

(I have not looked at your code yet, I'll do later)

1. The first is the overall redesign at a high level, how does everyone feel 
about the approach of
breaking it down for multiple protocols with a common downloader interface?

How will it look in practice? For WebKit, it is convenient that the protocol 
doesn't matter so much
and it's not so hard to write code for "I want to access this URL" without 
worrying about the
protocol, sessions, etc. Currently this works well for HTTP, data: and file: 
URLs, and somewhat ok
for Gopher (which is cheating a bit by making things look mostly like HTTP).

If the new protocol doesn't allow this, and each protocol needs to be handled 
separately, this means
more work to do on the WebKit side (but I can admit that WebKit is a special 
case here).

Likewise, one of the ideas in the TODO list is allowing the package kit to ue 
some p2p protocol to
download files. It would be nice if this meant only a change of URL in the repo 
configuration and
nothing else. That's probably not possible.

I think there is a compromise to do and the right approach is somewhere between 
"each protocol has
a completely independant API and applications need to special cases the ones 
they want", and "the
kit completely abstracts the details of the protocol so any advanced usage is 
not possible" ("advanced
usages" being things like range requests for downloading parts of an HTTP file, 
setting and reading
HTTP headers, using cookies, using active or passive mode for FTP, ...).

2. Then there is another discussion of how to implement this in the light of 
modern C++. The GCC
8.3 compiler has pretty complete C++17 support, and while I imagine there are 
different feelings
about modern C++ and the direction it is going, there is no denying it is 
here and that it makes
sense to start thinking and discussing what it means for Haiku. Initially my 
thought would be to
make the new API available both for the x86_gcc2 platform and the x86 
platform, but I am starting
to change my mind... I actually think I would like to keep the support on 
x86_gcc2 to a minimum (up
to the level that is needed for the package kit), and really go to places on 
the modern compiler.
This will make it so that we can take advantage of move semantics, smart 
pointers, constexpr, some
metaprogramming and new features in the standard library.

I am fine with using modern C++ here. There is no need to provide this API to 
BeOS legacy apps. If
we need to build the package kit and apps using it with gcc8, that's also 
possible.

It raises another question, however: will this "blend" nicely in with the other 
APIs in Haiku?
While it is fine to use all the modern things in the implementation, we have to 
be careful with
what we do in the public API to try to keep it consistent with other parts of 
the APIs.


3. And the final part is about how to approach this. This will obviously be a 
lot of work, and I do
not want to overload regular code review. There is also a question about how 
we vet and validate
the internal design. The options are:
(a) keep working in a separate repository, implement the gaps, do testing and 
error checking, and
when there is a minimum definition of done, then merge and refine it on the 
main repository
(b) go for a feature branch in the Haiku repository so that we can use 
regular methods of peer
review to make it progress properly
(c) work in a `netservices2` directory structure in the master branch and 
continue from there.

Personally I think it makes sense to go through code review in smaller pieces 
and discuss things
as we go. I'm not good at reviewing a large piece of code in a single run.

I don't see why it would be a separate repository. Feature branch or directory 
are both fine, just
pick what's easier. Probably a feature branch means it's easier to remove the 
existing kit and not
worry about compatibility with existing applications while the work is in 
progress.

It seems a good idea to select a sample of applications to convert to the new 
kit to see how it does
in real worls use cases. I think this should include WebKit and Package Kit, 
and probably also HaikuDepot
(which does a lot of REST/JSON things). Do we need another app to cover more 
use cases? Things like
Maps or Weather, for example?

-- 
Adrien.


Other related posts: