From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS4713 221.184.0.0/13 X-Spam-Status: No, score=-3.4 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.0 Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by dcvr.yhbt.net (Postfix) with ESMTP id D75911F424 for ; Sat, 21 Apr 2018 11:23:25 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id C27A0120A8E; Sat, 21 Apr 2018 20:23:23 +0900 (JST) Received: from dcvr.yhbt.net (dcvr.yhbt.net [64.71.152.64]) by neon.ruby-lang.org (Postfix) with ESMTPS id 5F082120A76 for ; Sat, 21 Apr 2018 20:23:18 +0900 (JST) Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 0B62A1F424; Sat, 21 Apr 2018 11:23:16 +0000 (UTC) Date: Sat, 21 Apr 2018 11:23:16 +0000 From: Eric Wong To: ruby-core@ruby-lang.org Message-ID: <20180421112316.GA15093@dcvr> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-ML-Name: ruby-core X-Mail-Count: 86639 Subject: [ruby-core:86639] Re: [Ruby trunk Feature#13618] [PATCH] auto fiber schedule for rb_wait_for_single_fd and rb_waitpid X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" samuel@oriontransfer.org wrote: > It would be also be pretty awesome if you could actually > supply a reactor to use, e.g. `Fiber.new(io_reactor: > my_reactor)`. In this case, blocking operations would call > `my_reactor.wait_readable(io)` and > `my_reactor.wait_writable(io)`. Something like this allows for > the IO policy to be more flexible than global per-process > reactor or other similar implementation. I'm still personally > against a global IO reactor as it's an unnecessary point of > thread contention and complexity (i.e. how does it work with > fork? does every IO operation require locking a mutex?) Global epoll FD is not anywhere close to being a point of thread contention in real-world usage, especially with current GVL. If epoll contention ever comes close to being a problem, I'll fix it in the Linux kernel. I worked on reducing that contention in the kernel a few years back but couldn't measure an improvement outside of synthetic benchmarks with the workload I had at the time (which wasn't ruby and had no GVL). Of course unbuffered IO operations will not require mutexes and fork is taken into consideration. For example, it accounts for native kqueue having unique close-on-fork behavior which no other FD type has. Btw, your use the word "reactor" is a bit lost on me. My view of epoll (and kqueue) is the sum of two data structures: a. map structure (rbtree, hash, etc...) b. readiness queue (why else does "kqueue" have the word "queue" in it)? And what happens is: 1. green thread gets stuck on IO 2. native thread epoll_ctl/kevent(changelist) to places items into a. 3. kernel puts items in a. into b. when they are ready 4. threads take items off b. via epoll_wait/kevent(eventlist) I don't think "reactor" describes that, because reactor pattern is rooted in a single thread mentality. epoll/kqueue invite parallelism. Now, I'm hungry, maybe it's the "restaurant kitchen pattern", and the analogy would be: 1. patrons order food from a waiter 2. waiters puts in orders into the kitchen 3. cooks work on orders, prepared plates are placed on the counter 4. waiters takes plates from counter and serves to patrons There can be any number of waiters and cooks working, and in no way are their quantities tied together. Each waiter can handle multiple patrons, but sequentially. Waiters may also put in orders for themselves. Some plates take a long time to prepare, some plates are quick; some plates are ready immediately. Many orders may come in at once, or they can trickle in. Many plates can be ready at once, or they can trickle out. cooks = native threads inside the kernel waiters = native threads seen by userspace patrons = green threads As with green threads and the kernel, cooks never see the patrons and don't know how many there are. Waiters don't care or know which cook prepares the plate they serve. Cooks don't care which waiter the plate goes to, either. > So, as mentioned earlier, `libpq` and the associated `pq` gems > won't suddenly become asynchronous because of this patch > (seems like there is a bit of a misunderstanding how this > works under the hood). In fact, we can already achieve massive > concurrency improvements using `async`, and I've tested this > using `puma` and `falcon`. The difference was pretty big! I > wrote up a summary here: > https://github.com/socketry/async-postgres#performance Of course things don't become asynchronous automatically. Again, I've seen this all before with Revactor, NeverBlock, etc. Problem is, if it's not in built-in, it'll likely end up unused or causing more ecosystem fragmentation. Lets not forget many languages ruby has lost users to (Go, Erlang) has similar lightweight threading primitives built-in. And again, I consider this work to be fixing a regression when we made the 1.8 -> 1.9 transition to native Thread. > feel free to come and chat in https://gitter.im/socketry/async > as there are a quite a few people there who are interested in > the direction of asynchronous IO in Ruby. Sorry, it's not reasonable to expect Free Software developers to rely on proprietary messaging platform like GitHub (which gitter depends on). > So, again, I think this patch is simply does too much. It > should be split into 1/ a standard IO reactor for Ruby with a > standard interface that others can implement (could easily be > a gem) Maybe exposing some parts of the mapping + queue API might be possible. Again, I don't think "reactor" is even the right pattern or word to describe what's going on, here.