vibe.d-lite v0.1.0 powered by photon

Dmitry Olshansky dmitry.olsh at gmail.com
Thu Sep 25 12:25:13 UTC 2025


On Thursday, 25 September 2025 at 07:24:00 UTC, Sönke Ludwig 
wrote:
> Am 23.09.25 um 17:35 schrieb Dmitry Olshansky:
>> On Monday, 22 September 2025 at 11:14:17 UTC, Sönke Ludwig 
>> wrote:
>>> Am 22.09.25 um 09:49 schrieb Dmitry Olshansky:
>>>> On Friday, 19 September 2025 at 17:37:36 UTC, Sönke Ludwig 
>>>> wrote:
>>>>> So you don't support timeouts when waiting for an event at 
>>>>> all? Otherwise I don't see why a separate API would be 
>>>>> required, this should be implementable with plain Posix 
>>>>> APIs within vibe-core-lite itself.
>>>>
>>>> Photon's API is the syscall interface. So to wait on an 
>>>> event you just call poll.
>>>> Behind the scenes it will just wait on the right fd to 
>>>> change state.
>>>>
>>>> Now vibe-core-light wants something like read(buffer, 
>>>> timeout) which is not syscall API but maybe added. But since 
>>>> I'm going to add new API I'd rather have something 
>>>> consistent and sane not just a bunch of adhoc functions to 
>>>> satisfy vibe.d interface.
>>>
>>> Why can't you then use poll() to for example implement 
>>> `ManualEvent` with timeout and interrupt support? And 
>>> shouldn't recv() with timeout be implementable the same way, 
>>> poll with timeout and only read when ready?
>> 
>> Yes, recv with timeout is basically poll+recv. The problem is 
>> that then I need to support interrupts in poll. Nothing really 
>> changed.
>> As far as manual event goes I've implemented that with custom 
>> cond var and mutex. That mutex is not interruptible as it's 
>> backed by semaphore on slow path in a form of eventfd.
>> I might create custom mutex that is interruptible I guess but 
>> the notion of interrupts would have to be introduced to 
>> photon. I do not really like it.
>
> I'd probably create an additional event FD per thread used to 
> signal interruption and also pass that to any poll() that is 
> used for interruptible wait.

poll could be made interruptible w/o any additions it's really a 
yield + waiting for events. I could implement interruptible 
things by simply waking fiber up with special flag
passed (it has such to determine which event waked us up anyway).

The problem is, I do not see how to provide adequate interface 
for this functionality.
I have an idea though - use EINTR or maybe devise my own code for 
interrupts, then I could interrupt at my syscall interface level. 
Next is the question of how do I throw from a nothrow context. 
Here I told you that I would need a separate APIs for 
interruptible things - the ones that allow interrupts. *This* is 
something I do not look forward to.

>>> I think we have a misunderstanding of what vibe.d is supposed 
>>> to be. It seems like you are only focused on the web/server 
>>> role, while to me vibe-core is a general-purpose I/O and 
>>> concurrency system with no particular specialization in 
>>> server tasks. With that view, your statement to me sounds 
>>> like "Clearly D is not meant to do multi- threading, since 
>>> main() is only running in a single thread".
>> 
>> The defaults are what is important. Go defaults to 
>> multi-threading for instance.
>> D defaults to multi-threading because TLS by default is 
>> certainly a mark of multi-threaded environment. 
>> std.concurrency defaults to new thread per spawn, again this 
>> tells me it's about multithreading. I intend to support 
>> multi-threading by default. I understand that we view this 
>> issue differently.
>
> But you are comparing different defaults here. With plain D, 
> you also have to import either `core.thread` or 
> `std.concurrency`/`std.paralellism` to do any multi-threaded 
> work. The same is true for vibe-core. What you propose would be 
> more comparable to having foreach() operate like 
> parallelForeach(), with far-reaching consequences.
>
> If we are just talking about naming - runTask/runWorkerTask vs. 
> go/goOnSameThread - that is of course debatable, but in that 
> case I think it's blown very much out of proportion to take 
> that as the basis to claim "it's meant to be used 
> single-threaded".

So runTask is assumed to run on the same core while runWorkerTask 
to be run on any available core? Didn't occur to me. I thought 
worker pool is for blocking tasks, as there is such a pool in 
photon. I can just switch runTask to goOnSameThread to maximize 
compatibility with vibed.

>> 
>> Channels tame the complexity. Yes, channels could get more 
>> expansive in multi-threaded scenario but we already agreed 
>> that it's not CPU bound.
>
> If you have code that does a lot of these things, this just 
> degrades code readability for absolutely no practical gain, 
> though.

I humbly disagree. I'd take explicit channels over global TLS 
variables any day.

>>>>> This doesn't make sense, in the original vibe-core, you can 
>>>>> simply choose between spawning in the same thread or in 
>>>>> "any" thread. `shared`/`immutable` is correctly enforced in 
>>>>> the latter case to avoid unintended data sharing.
>>>>
>>>> I have go and goOnSameThread. Guess which is the encouraged 
>>>> option.
>>>
>>> Does go() enforce proper use of shared/immutable when passing 
>>> data to the scheduled "go routine"?
>> 
>> It goes with the same API as we have for threads - a delegate, 
>> so sharing becomes user's responsibility. I may add function + 
>> args for better handling of resources passed to the lambda.
>
> That means that this is completely un`@safe` - C++ level memory 
> safety. IMO this is an unacceptable default for web 
> applications.

Yeah, I'm not in the @safe world mostly. But as I said to make it 
more upstreamable I will switch the defaults, so that 
vibe-core-light provides the same guarantees as regular vibe-core 
does.

>>> malloc() will also always be a bottleneck with the right 
>>> load. Just the n times larger amount of virtual address space 
>>> required may start to become an issue for memory heavy 
>>> applications. But even if ignore that, ruling out using the 
>>> existing GC doesn't sound like a good idea to me.
>> 
>> The existing GC is basically 20+ years old, ofc we need better 
>> GC and
>> thread cached allocation solves contention in multi-threaded 
>> environments.
>> Alternative memory allocator is doing great on 320 core 
>> machines. I cannot tell you which allocator that is or what 
>> exactly these servers are. Though even jemalloc does okayish.
>> 
>>> And the fact is that, even with relatively mild GC use, a web 
>>> application will not scale properly with many cores.
>> 
>> Only partially agree, Java's GC handles load just fine and 
>> runs faster than vibe.d(-light). It does allocations on its 
>> serving code path.
>
> I was just talking about the current D GC here. Once we have a 
> better implementation, this can very well become a much weaker 
> argument!
>
> However, speaking more generally, the other arguments for 
> preferring to scale using processes still stand, and even with 
> a better GC I would still argue that leading library users to 
> do multi-threaded request handling is not necessarily the best 
> default (of course it still *can* be for some applications).

I'm betting more on the threaded approach, but we are just 
different. See also my reply on the numbers - processes are only 
about 1-2% faster (and the noise is easily in 0.5% range) once 
the GC bottleneck is handled that is.

> Anyway, the main point from my side is just that the semantics 
> of what *is* in vibe-core-light should really match the 
> corresponding functions in vibe-core. Apart from that, I was 
> just telling you that your impression of it being intended to 
> be used single-threaded is not right, which doesn't mean that 
> the presentation shouldn't probably emphasize the 
> multi-threaded functionality and multi-threaded request 
> processing more.

Given the number of potential expectations from the user side it 
seems I need to update vibe-core-light to use goOnSameThread for 
runTask. I do not like it how I need to do extra work to launch a 
multi-threaded server though which is something that got me 
started on the whole "defaults argument".



More information about the Digitalmars-d-announce mailing list