2019-08-07 13:01:22 +02:00
|
|
|
//
|
2022-01-01 01:35:39 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
2019-08-07 13:01:22 +02:00
|
|
|
//
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
//
|
|
|
|
#pragma once
|
|
|
|
|
2020-06-11 15:43:26 +02:00
|
|
|
#include "td/utils/common.h"
|
2022-06-27 12:30:18 +02:00
|
|
|
#include "td/utils/Promise.h"
|
2020-06-11 15:43:26 +02:00
|
|
|
#include "td/utils/Slice.h"
|
2019-08-07 13:01:22 +02:00
|
|
|
#include "td/utils/Span.h"
|
2020-06-11 15:43:26 +02:00
|
|
|
#include "td/utils/Status.h"
|
|
|
|
#include "td/utils/StringBuilder.h"
|
2019-08-07 13:01:22 +02:00
|
|
|
|
|
|
|
#include <map>
|
2020-06-11 15:43:26 +02:00
|
|
|
#include <memory>
|
|
|
|
#include <utility>
|
2019-08-07 13:01:22 +02:00
|
|
|
|
|
|
|
namespace td {
|
|
|
|
|
|
|
|
class TQueue {
|
|
|
|
public:
|
|
|
|
class EventId {
|
|
|
|
public:
|
2020-06-11 15:43:26 +02:00
|
|
|
static constexpr int32 MAX_ID = 2000000000;
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
EventId();
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
static Result<EventId> from_int32(int32 id);
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2020-06-11 22:54:56 +02:00
|
|
|
bool is_valid() const;
|
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
int32 value() const;
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
Result<EventId> next() const;
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
Result<EventId> advance(size_t offset) const;
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
bool empty() const;
|
|
|
|
|
|
|
|
bool operator==(const EventId &other) const;
|
2020-06-11 17:12:16 +02:00
|
|
|
bool operator!=(const EventId &other) const;
|
2019-08-27 17:06:00 +02:00
|
|
|
bool operator<(const EventId &other) const;
|
2019-08-07 13:01:22 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
int32 id_{0};
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
explicit EventId(int32 id);
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2020-06-11 22:54:56 +02:00
|
|
|
static bool is_valid_id(int32 id);
|
2019-08-07 13:01:22 +02:00
|
|
|
};
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
struct Event {
|
|
|
|
EventId id;
|
2021-10-21 11:51:16 +02:00
|
|
|
int32 expires_at{0};
|
2019-08-07 13:01:22 +02:00
|
|
|
Slice data;
|
2019-09-06 17:55:19 +02:00
|
|
|
int64 extra{0};
|
2019-08-07 13:01:22 +02:00
|
|
|
};
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
struct RawEvent {
|
2020-09-22 01:15:09 +02:00
|
|
|
uint64 log_event_id{0};
|
2019-08-07 13:01:22 +02:00
|
|
|
EventId event_id;
|
|
|
|
string data;
|
2019-09-06 17:55:19 +02:00
|
|
|
int64 extra{0};
|
2020-08-06 03:02:54 +02:00
|
|
|
int32 expires_at{0};
|
2019-08-07 13:01:22 +02:00
|
|
|
};
|
2020-06-11 17:12:16 +02:00
|
|
|
|
|
|
|
using QueueId = int64;
|
|
|
|
|
2020-06-11 22:54:56 +02:00
|
|
|
class StorageCallback {
|
2019-08-07 13:01:22 +02:00
|
|
|
public:
|
|
|
|
using QueueId = TQueue::QueueId;
|
|
|
|
using RawEvent = TQueue::RawEvent;
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2020-06-11 22:54:56 +02:00
|
|
|
StorageCallback() = default;
|
|
|
|
StorageCallback(const StorageCallback &) = delete;
|
|
|
|
StorageCallback &operator=(const StorageCallback &) = delete;
|
|
|
|
StorageCallback(StorageCallback &&) = delete;
|
|
|
|
StorageCallback &operator=(StorageCallback &&) = delete;
|
|
|
|
virtual ~StorageCallback() = default;
|
2020-06-11 17:12:16 +02:00
|
|
|
|
2020-06-11 15:52:39 +02:00
|
|
|
virtual uint64 push(QueueId queue_id, const RawEvent &event) = 0;
|
2020-09-22 01:15:09 +02:00
|
|
|
virtual void pop(uint64 log_event_id) = 0;
|
2020-07-14 19:54:38 +02:00
|
|
|
virtual void close(Promise<> promise) = 0;
|
2019-08-07 13:01:22 +02:00
|
|
|
};
|
|
|
|
|
2020-06-11 17:12:16 +02:00
|
|
|
static unique_ptr<TQueue> create();
|
|
|
|
|
|
|
|
TQueue() = default;
|
|
|
|
TQueue(const TQueue &) = delete;
|
|
|
|
TQueue &operator=(const TQueue &) = delete;
|
|
|
|
TQueue(TQueue &&) = delete;
|
|
|
|
TQueue &operator=(TQueue &&) = delete;
|
|
|
|
|
|
|
|
virtual ~TQueue() = default;
|
|
|
|
|
2020-06-11 22:54:56 +02:00
|
|
|
virtual void set_callback(unique_ptr<StorageCallback> callback) = 0;
|
|
|
|
virtual unique_ptr<StorageCallback> extract_callback() = 0;
|
2019-08-07 17:29:47 +02:00
|
|
|
|
2020-06-12 02:02:20 +02:00
|
|
|
virtual bool do_push(QueueId queue_id, RawEvent &&raw_event) = 0;
|
2019-08-07 13:01:22 +02:00
|
|
|
|
2020-08-06 03:02:54 +02:00
|
|
|
virtual Result<EventId> push(QueueId queue_id, string data, int32 expires_at, int64 extra, EventId hint_new_id) = 0;
|
2019-08-07 13:01:22 +02:00
|
|
|
|
2019-08-27 17:06:00 +02:00
|
|
|
virtual void forget(QueueId queue_id, EventId event_id) = 0;
|
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
virtual EventId get_head(QueueId queue_id) const = 0;
|
|
|
|
virtual EventId get_tail(QueueId queue_id) const = 0;
|
|
|
|
|
2020-08-06 03:02:54 +02:00
|
|
|
virtual Result<size_t> get(QueueId queue_id, EventId from_id, bool forget_previous, int32 unix_time_now,
|
2020-06-11 17:12:16 +02:00
|
|
|
MutableSpan<Event> &result_events) = 0;
|
2019-08-07 13:01:22 +02:00
|
|
|
|
2020-08-26 20:36:29 +02:00
|
|
|
virtual size_t get_size(QueueId queue_id) const = 0;
|
2020-06-24 14:11:39 +02:00
|
|
|
|
2020-08-07 18:36:23 +02:00
|
|
|
virtual int64 run_gc(int32 unix_time_now) = 0;
|
2020-07-14 19:54:38 +02:00
|
|
|
virtual void close(Promise<> promise) = 0;
|
2019-08-07 13:01:22 +02:00
|
|
|
};
|
|
|
|
|
2021-10-18 18:26:14 +02:00
|
|
|
StringBuilder &operator<<(StringBuilder &string_builder, TQueue::EventId id);
|
2019-08-07 13:01:22 +02:00
|
|
|
|
|
|
|
struct BinlogEvent;
|
2020-06-11 15:43:26 +02:00
|
|
|
|
2019-08-07 13:01:22 +02:00
|
|
|
template <class BinlogT>
|
2021-07-04 04:58:54 +02:00
|
|
|
class TQueueBinlog final : public TQueue::StorageCallback {
|
2019-08-07 13:01:22 +02:00
|
|
|
public:
|
2021-07-03 22:51:36 +02:00
|
|
|
uint64 push(QueueId queue_id, const RawEvent &event) final;
|
|
|
|
void pop(uint64 log_event_id) final;
|
2020-07-24 05:57:48 +02:00
|
|
|
Status replay(const BinlogEvent &binlog_event, TQueue &q) const TD_WARN_UNUSED_RESULT;
|
2019-08-07 13:01:22 +02:00
|
|
|
|
|
|
|
void set_binlog(std::shared_ptr<BinlogT> binlog) {
|
|
|
|
binlog_ = std::move(binlog);
|
|
|
|
}
|
2021-10-18 18:26:14 +02:00
|
|
|
void close(Promise<> promise) final;
|
2019-08-07 13:01:22 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::shared_ptr<BinlogT> binlog_;
|
2020-08-06 03:02:54 +02:00
|
|
|
static constexpr int32 BINLOG_EVENT_TYPE = 2314;
|
2019-08-07 13:01:22 +02:00
|
|
|
};
|
|
|
|
|
2021-07-04 04:58:54 +02:00
|
|
|
class TQueueMemoryStorage final : public TQueue::StorageCallback {
|
2019-08-07 13:01:22 +02:00
|
|
|
public:
|
2021-07-03 22:51:36 +02:00
|
|
|
uint64 push(QueueId queue_id, const RawEvent &event) final;
|
|
|
|
void pop(uint64 log_event_id) final;
|
2020-06-12 02:02:20 +02:00
|
|
|
void replay(TQueue &q) const;
|
2021-10-18 18:26:14 +02:00
|
|
|
void close(Promise<> promise) final;
|
2019-08-07 13:01:22 +02:00
|
|
|
|
|
|
|
private:
|
2020-09-22 01:15:09 +02:00
|
|
|
uint64 next_log_event_id_{1};
|
2020-06-11 15:52:39 +02:00
|
|
|
std::map<uint64, std::pair<QueueId, RawEvent>> events_;
|
2019-08-07 13:01:22 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace td
|