Skip to content

Instantly share code, notes, and snippets.

@danmayer
Created November 3, 2020 21:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danmayer/975992e393d9e072f5c47f6dce535444 to your computer and use it in GitHub Desktop.
Save danmayer/975992e393d9e072f5c47f6dce535444 to your computer and use it in GitHub Desktop.
# frozen_string_literal: true
class SlowCall
def self.work
@work ||= Concurrent::Promises.future(name: "load #{self.class.name}") do
sleep 2
Time.now
end
end
end
class FastCall
def self.work
Concurrent::Promises.future(name: "load #{self.class.name}") do
Time.now
end
end
end
class OrCall
def self.work
(SlowCall.work | FastCall.work)
end
end
class AndCall
def self.work
(SlowCall.work & FastCall.work).then { |a, b| a && b }
end
end
class EarlyReturnCall
def self.work
Concurrent::Promises.fulfilled_future(Time.now)
end
end
require 'spec_helper'
RSpec.describe "promises" do
describe 'promises' do
context "concurrency" do
it "is concurrent" do
time = Time.now
slow, fast, or_call, and_call, early_call = Concurrent::Promises.zip(
SlowCall.work,
FastCall.work,
OrCall.work,
AndCall.work,
EarlyReturnCall.work,
).value!
expect(slow).to be_within(3.second).of(time)
expect(fast).to be_within(1.second).of(time)
expect(or_call).to be_within(1.second).of(time)
expect(and_call).to be_within(3.second).of(time)
expect(early_call).to be_within(1.second).of(time)
end
it "is memoized" do
time = Time.now
_slow, _slow = Concurrent::Promises.zip(
SlowCall.work,
SlowCall.work,
SlowCall.work,
).value!
result = SlowCall.work.value!
expect(result).to be_within(3.second).of(time)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment