From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS24940 94.130.0.0/16 X-Spam-Status: No, score=-2.9 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_BL_SPAMCOP_NET,SPF_HELO_PASS, SPF_PASS,UNPARSEABLE_RELAY shortcircuit=no autolearn=no autolearn_force=no version=3.4.2 Received: from nue.mailmanlists.eu (nue.mailmanlists.eu [94.130.110.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id C41C91F4C1 for ; Wed, 30 Nov 2022 17:12:03 +0000 (UTC) Authentication-Results: dcvr.yhbt.net; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ruby-lang.org header.i=@ruby-lang.org header.b="X743g4gd"; dkim-atps=neutral Received: from nue.mailmanlists.eu (localhost [127.0.0.1]) by nue.mailmanlists.eu (Postfix) with ESMTP id 8206D7E79B; Wed, 30 Nov 2022 17:11:56 +0000 (UTC) Authentication-Results: nue.mailmanlists.eu; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ruby-lang.org header.i=@ruby-lang.org header.a=rsa-sha256 header.s=s1 header.b=X743g4gd; dkim-atps=neutral Received: from o1678948x4.outbound-mail.sendgrid.net (o1678948x4.outbound-mail.sendgrid.net [167.89.48.4]) by nue.mailmanlists.eu (Postfix) with ESMTPS id BAAE47E6C0 for ; Wed, 30 Nov 2022 17:11:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ruby-lang.org; h=from:references:subject:mime-version:content-type: content-transfer-encoding:list-id:to:cc; s=s1; bh=G05IKkeJqyD2JNm7vtoQSRXOa1Pq+G+C5r/M7YxpEQI=; b=X743g4gdVLxfbrwYhbEnkMd++jQPQr/TcL+Aed7J9a3QoapPfNttfaLt1z5Cbc4gQ4gP D5puZKxinjE3sh40LG4he2KYNuoO28j4HqMLZdEUQvGB2wDAVcb9pu9IOokEI3HtTfMU2F mI3eIEZE3WgILMjBFb7g1OVTVscYUblJRwRzU2c4VFMBBv0c0zIY8LINdHZ1TR4cALdcg4 1ByWG6fa2lOQb6KgrcK4Zw5XplpAIGiVSsvH9UmxOU8NxhxxXVLmp1/NpZR3TG4Y23VSLL MfjxRXb6JeFc34E1KIOYtWIcvxg5xOazVoKLGc+IH9Iw4Al+kI9kfyy2UlOrNJXA== Received: by filterdrecv-6c4ccfbdd8-x5hs5 with SMTP id filterdrecv-6c4ccfbdd8-x5hs5-1-63878ED6-29 2022-11-30 17:11:50.552109471 +0000 UTC m=+1101971.310264111 Received: from herokuapp.com (unknown) by geopod-ismtpd-1-1 (SG) with ESMTP id ZkCAjLcoSIykrjRKQRtr6w for ; Wed, 30 Nov 2022 17:11:50.437 +0000 (UTC) Date: Wed, 30 Nov 2022 17:11:50 +0000 (UTC) From: "Dan0042 (Daniel DeLorme)" Message-ID: References: Mime-Version: 1.0 X-Redmine-Project: ruby-master X-Redmine-Issue-Tracker: Feature X-Redmine-Issue-Id: 19078 X-Redmine-Issue-Author: ioquatix X-Redmine-Issue-Assignee: ioquatix X-Redmine-Sender: Dan0042 X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-Redmine-MailingListIntegration-Message-Ids: 87442 X-SG-EID: =?us-ascii?Q?9vnO9kNFlf1pwhty1clU3mt9eNWYniufdXqocdsQQtaDTWZk4+b5g5js0Akvaj?= =?us-ascii?Q?32LW=2F+fGSAom3tt8Jo+=2FGW3uDD0ktbmu7qAbln0?= =?us-ascii?Q?uJrjIAt9kqdpQDRRp8XpQRhulumJqy0TdAssg=2Fw?= =?us-ascii?Q?TT9D+xWNlrIRjWp2vs23XLZxaoRr1RO9ImhIm9R?= =?us-ascii?Q?IDeZmtbzBXof02fKHJYCtQDF0UtRcOOHqZL+2HL?= =?us-ascii?Q?FczJIQlaZauHUx7CIe1TPSu5FrFHBB+WyEjirLT?= =?us-ascii?Q?Nc=2FqhWqCShTAupJUMz+hg=3D=3D?= To: ruby-core@ml.ruby-lang.org X-Entity-ID: b/2+PoftWZ6GuOu3b0IycA== Message-ID-Hash: HNLX6DSLGXO5RIHH6MXAZHP22GUHZKEC X-Message-ID-Hash: HNLX6DSLGXO5RIHH6MXAZHP22GUHZKEC X-MailFrom: bounces+313651-b711-ruby-core=ml.ruby-lang.org@em5188.ruby-lang.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.3 Precedence: list Reply-To: Ruby developers Subject: [ruby-core:111092] [Ruby master Feature#19078] Introduce `Fiber#storage` for inheritable fiber-scoped variables. List-Id: Ruby developers Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Issue #19078 has been updated by Dan0042 (Daniel DeLorme). Maybe I'm too late here, but I have some thoughts/concerns about this. First I should say I totally agree with the general idea. We need some way to inherit "context state". So far I've seen 2 use cases described. 1 - store a request_id or correlation_id, for logging purposes (or even the full request object) 2 - store a connection (typically database) that can't be used at the same time by another thread/fiber It would be nice if we had 1-2 other use cases; that would allow to evaluate this design from more angles. We already have per-thread-but-actually-fiber storage, and a really-per-thread storage, and this is adding a third type. What about when we want per-ractor storage... a fourth type? Per-ractor inheritable storage... a fifth type? Rather than fragmenting storages I would prefer to unify them. Maybe it's a crazy idea, but what if we set fiber-inheritable values via `Thread.current.store(k, v, level: Fiber, inherit: true)` and read them via `Thread.current[k]` ? For writing it's a somewhat complex/advanced interface, but choosing which storage to use is a complex/advanced question anyway. And when reading a value I think we typically don't care about which storage it is in; it would be easier to have a single point of access. When should a value be inherited? For usecase#1 (request_id), it seems to be all the time. But for usecase#2 (connection) I think it varies. If you have a sub-fiber that does its own requests to the DB, you don't want to inherit the connection. But if it's an iterator fiber you do want to inherit the connection. So it depends on what "kind" of fiber, how it is used. Actually, for an iterator fiber, you'd probably want to inherit all state, even if it wasn't explicitly specified as inheritable. So maybe something like `Fiber.new(inherit: true)` would be better for that case. What about when transfering control from one fiber to another? ```ruby producer = Fiber.new{loop{ puts "on behalf of #{Thread.current[:request_id] || '?'}" puts "producing #{v=rand}" Fiber.yield(v) }} Thread.current[:request_id] = SecureRandom.hex(16) producer.resume #=> random value ``` In the code above we could argue that the producer should "inherit" the request_id via resume. ---------------------------------------- Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables. https://bugs.ruby-lang.org/issues/19078#change-100357 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal * Assignee: ioquatix (Samuel Williams) ---------------------------------------- Pull Request: https://github.com/ruby/ruby/pull/6612 This is an evolution of the previous ideas: - https://bugs.ruby-lang.org/issues/19058 - https://bugs.ruby-lang.org/issues/19062 This PR introduces fiber scoped variables, and is a solution for problems like . The main interface is: ```ruby Fiber[key] = value Fiber[key] # => value ``` The variables are scoped (local to) a fiber and inherited into child fibers and threads. ```ruby Fiber[:request_id] = SecureRandom.hex(16) Fiber.new do p Fiber[:request_id] # prints the above request id end ``` The fiber scoped variables are stored and can be accessed: ```ruby Fiber.current.storage # => returns a Hash (copy) of the internal storage. Fiber.current.storage= # => assigns a Hash (copy) to the internal storage. ``` Fiber itself has one new keyword argument: ``` Fiber.new(..., storage: hash, false, undef, nil) ``` This can control how the fiber variables are setup in a child context. To minimise the performance overhead of some of the implementation choices, we are also simultaneously implementing . ## Examples ### Request loop ```ruby Thread.new do while request = queue.pop Fiber.new(storage: {id: SecureRandom.hex(16)}) do handle_request.call(request) end end end ``` OR ```ruby Thread.new do while request = queue.pop Fiber.current.storage = {id: SecureRandom.hex(16)} handle_request.call(request) end end ``` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/