forked from scylladb/scylladb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsequential_producer.hh
46 lines (38 loc) · 1.15 KB
/
sequential_producer.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
* Copyright (C) 2021 ScyllaDB
*/
/*
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
*/
#pragma once
#include <functional>
#include <seastar/core/shared_future.hh>
#include <stdexcept>
/// Invokes a factory to produce an object, but sequentially: only one fiber at a time may be executing the
/// factory. Any other fiber requesting the object will wait for the existing factory invocation to finish, then
/// copy the result.
///
/// TODO: Move to Seastar.
template<typename T>
class sequential_producer {
public:
using factory_t = std::function<seastar::future<T>()>;
private:
factory_t _factory;
seastar::shared_future<T> _churning; ///< Resolves when the previous _factory call completes.
public:
sequential_producer(factory_t&& f) : _factory(std::move(f))
{
clear();
}
seastar::future<T> operator()() {
if (_churning.available()) {
_churning = _factory();
}
return _churning.get_future();
}
void clear() {
_churning = seastar::make_exception_future<T>(
std::logic_error("initial future used in sequential_producer"));
}
};