Support scheduled message in MessageId::get_next_message_id. Add get_next_yet_unsent_scheduled_message_id.
GitOrigin-RevId: dfe0c0b13c6312525564eba9f10f390f5ad09778
This commit is contained in:
parent
57eb92060b
commit
f3dfaa6c29
@ -11,12 +11,12 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
MessageId::MessageId(ScheduledServerMessageId server_message_id, int32 send_date) {
|
||||
MessageId::MessageId(ScheduledServerMessageId server_message_id, int32 send_date, bool force) {
|
||||
if (send_date <= (1 << 30)) {
|
||||
LOG(ERROR) << "Scheduled message send date " << send_date << " is in the past";
|
||||
return;
|
||||
}
|
||||
if (!server_message_id.is_valid()) {
|
||||
if (!server_message_id.is_valid() && !force) {
|
||||
LOG(ERROR) << "Scheduled message ID " << server_message_id.get() << " is invalid";
|
||||
return;
|
||||
}
|
||||
@ -46,6 +46,20 @@ MessageType MessageId::get_type() const {
|
||||
if (id <= 0 || id > max().get()) {
|
||||
return MessageType::None;
|
||||
}
|
||||
|
||||
if (is_scheduled()) {
|
||||
switch (id & TYPE_MASK) {
|
||||
case SCHEDULED_MASK | TYPE_YET_UNSENT:
|
||||
return MessageType::YetUnsent;
|
||||
case SCHEDULED_MASK | TYPE_LOCAL:
|
||||
return MessageType::Local;
|
||||
case SCHEDULED_MASK:
|
||||
return MessageType::Server;
|
||||
default:
|
||||
return MessageType::None;
|
||||
}
|
||||
}
|
||||
|
||||
if ((id & FULL_TYPE_MASK) == 0) {
|
||||
return MessageType::Server;
|
||||
}
|
||||
@ -65,14 +79,37 @@ ServerMessageId MessageId::get_server_message_id_force() const {
|
||||
}
|
||||
|
||||
MessageId MessageId::get_next_message_id(MessageType type) const {
|
||||
CHECK(!is_scheduled());
|
||||
if (is_scheduled()) {
|
||||
CHECK(is_valid_scheduled());
|
||||
auto current_type = get_type();
|
||||
if (static_cast<int32>(current_type) < static_cast<int32>(type)) {
|
||||
return MessageId(id - static_cast<int32>(current_type) + static_cast<int32>(type));
|
||||
}
|
||||
int64 base_id = (id & ~TYPE_MASK) + TYPE_MASK + 1 + SCHEDULED_MASK;
|
||||
switch (type) {
|
||||
case MessageType::Server:
|
||||
return MessageId(base_id);
|
||||
case MessageType::YetUnsent:
|
||||
return MessageId(base_id + TYPE_YET_UNSENT);
|
||||
case MessageType::Local:
|
||||
return MessageId(base_id + TYPE_LOCAL);
|
||||
case MessageType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return MessageId();
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MessageType::Server:
|
||||
if (is_server()) {
|
||||
return MessageId(ServerMessageId(get_server_message_id().get() + 1));
|
||||
}
|
||||
return get_next_server_message_id();
|
||||
case MessageType::Local:
|
||||
return MessageId(((id + TYPE_MASK + 1 - TYPE_LOCAL) & ~TYPE_MASK) + TYPE_LOCAL);
|
||||
case MessageType::YetUnsent:
|
||||
return MessageId(((id + TYPE_MASK + 1 - TYPE_YET_UNSENT) & ~TYPE_MASK) + TYPE_YET_UNSENT);
|
||||
case MessageType::Local:
|
||||
return MessageId(((id + TYPE_MASK + 1 - TYPE_LOCAL) & ~TYPE_MASK) + TYPE_LOCAL);
|
||||
case MessageType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
enum class MessageType : int32 { None, Server, Local, YetUnsent };
|
||||
enum class MessageType : int32 { None, Server, YetUnsent, Local };
|
||||
|
||||
class MessageId {
|
||||
int64 id = 0;
|
||||
@ -55,7 +55,7 @@ class MessageId {
|
||||
: id(static_cast<int64>(server_message_id.get()) << SERVER_ID_SHIFT) {
|
||||
}
|
||||
|
||||
MessageId(ScheduledServerMessageId server_message_id, int32 send_date);
|
||||
MessageId(ScheduledServerMessageId server_message_id, int32 send_date, bool force = false);
|
||||
|
||||
explicit constexpr MessageId(int64 message_id) : id(message_id) {
|
||||
}
|
||||
@ -131,6 +131,11 @@ class MessageId {
|
||||
return get_scheduled_server_message_id_force();
|
||||
}
|
||||
|
||||
int32 get_scheduled_message_date() const {
|
||||
CHECK(is_valid_scheduled());
|
||||
return static_cast<int32>(id >> 21) + (1 << 30);
|
||||
}
|
||||
|
||||
bool operator==(const MessageId &other) const {
|
||||
return id == other.id;
|
||||
}
|
||||
|
@ -16901,7 +16901,8 @@ MessagesManager::Message *MessagesManager::get_message_to_send(Dialog *d, Messag
|
||||
int32 schedule_date = 0;
|
||||
bool is_scheduled = schedule_date != 0;
|
||||
CHECK(d != nullptr);
|
||||
MessageId message_id = get_next_yet_unsent_message_id(d); // TODO support sending scheduled messages
|
||||
MessageId message_id =
|
||||
is_scheduled ? get_next_yet_unsent_scheduled_message_id(d, schedule_date) : get_next_yet_unsent_message_id(d);
|
||||
DialogId dialog_id = d->dialog_id;
|
||||
LOG(INFO) << "Create " << message_id << " in " << dialog_id;
|
||||
|
||||
@ -22309,6 +22310,20 @@ MessageId MessagesManager::get_next_local_message_id(Dialog *d) {
|
||||
return get_next_message_id(d, MessageType::Local);
|
||||
}
|
||||
|
||||
MessageId MessagesManager::get_next_yet_unsent_scheduled_message_id(const Dialog *d, int32 date) {
|
||||
CHECK(date > 0);
|
||||
auto it = MessagesConstIterator(d, MessageId(ScheduledServerMessageId(), date + 1, true));
|
||||
int32 prev_date = 0;
|
||||
if (*it != nullptr) {
|
||||
prev_date = (*it)->message_id.get_scheduled_message_date();
|
||||
}
|
||||
if (prev_date < date) {
|
||||
return MessageId(ScheduledServerMessageId(1), date).get_next_message_id(MessageType::YetUnsent);
|
||||
}
|
||||
CHECK(*it != nullptr);
|
||||
return (*it)->message_id.get_next_message_id(MessageType::YetUnsent);
|
||||
}
|
||||
|
||||
void MessagesManager::fail_send_message(FullMessageId full_message_id, int error_code, const string &error_message) {
|
||||
auto dialog_id = full_message_id.get_dialog_id();
|
||||
Dialog *d = get_dialog(dialog_id);
|
||||
@ -22331,9 +22346,9 @@ void MessagesManager::fail_send_message(FullMessageId full_message_id, int error
|
||||
// dump_debug_message_op(d, 5);
|
||||
}
|
||||
|
||||
MessageId new_message_id;
|
||||
MessageId new_message_id =
|
||||
old_message_id.get_next_message_id(MessageType::Local); // trying to not change message place
|
||||
if (!old_message_id.is_scheduled()) {
|
||||
new_message_id = old_message_id.get_next_message_id(MessageType::Local); // trying to not change message place
|
||||
if (get_message_force(d, new_message_id, "fail_send_message") != nullptr ||
|
||||
d->deleted_message_ids.count(new_message_id) || new_message_id <= d->last_clear_history_message_id) {
|
||||
new_message_id = get_next_local_message_id(d);
|
||||
@ -22341,11 +22356,9 @@ void MessagesManager::fail_send_message(FullMessageId full_message_id, int error
|
||||
d->last_assigned_message_id = new_message_id;
|
||||
}
|
||||
} else {
|
||||
new_message_id = MessageId(old_message_id.get() + 1); // trying to not change message place
|
||||
if (get_message_force(d, new_message_id, "fail_send_message") != nullptr ||
|
||||
d->deleted_message_ids.count(new_message_id)) {
|
||||
// TODO
|
||||
// new_message_id = get_next_scheduled_local_message_id(d);
|
||||
while (get_message_force(d, new_message_id, "fail_send_message") != nullptr ||
|
||||
d->deleted_message_ids.count(new_message_id)) {
|
||||
new_message_id = new_message_id.get_next_message_id(MessageType::Local);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25780,11 +25793,11 @@ void MessagesManager::do_delete_message_logevent(const DeleteMessageLogEvent &lo
|
||||
|
||||
void MessagesManager::attach_message_to_previous(Dialog *d, MessageId message_id, const char *source) {
|
||||
CHECK(d != nullptr);
|
||||
CHECK(message_id.is_valid());
|
||||
MessagesIterator it(d, message_id);
|
||||
Message *m = *it;
|
||||
CHECK(m != nullptr);
|
||||
CHECK(m->message_id == message_id);
|
||||
CHECK(m->message_id.is_valid());
|
||||
LOG_CHECK(m->have_previous) << d->dialog_id << " " << message_id << " " << source;
|
||||
--it;
|
||||
LOG_CHECK(*it != nullptr) << d->dialog_id << " " << message_id << " " << source;
|
||||
@ -25798,11 +25811,11 @@ void MessagesManager::attach_message_to_previous(Dialog *d, MessageId message_id
|
||||
|
||||
void MessagesManager::attach_message_to_next(Dialog *d, MessageId message_id, const char *source) {
|
||||
CHECK(d != nullptr);
|
||||
CHECK(message_id.is_valid());
|
||||
MessagesIterator it(d, message_id);
|
||||
Message *m = *it;
|
||||
CHECK(m != nullptr);
|
||||
CHECK(m->message_id == message_id);
|
||||
CHECK(m->message_id.is_valid());
|
||||
LOG_CHECK(m->have_next) << d->dialog_id << " " << message_id << " " << source;
|
||||
++it;
|
||||
LOG_CHECK(*it != nullptr) << d->dialog_id << " " << message_id << " " << source;
|
||||
@ -28064,7 +28077,8 @@ MessagesManager::Message *MessagesManager::continue_send_message(DialogId dialog
|
||||
auto now = G()->unix_time();
|
||||
bool is_scheduled = m->message_id.is_scheduled();
|
||||
|
||||
m->message_id = get_next_yet_unsent_message_id(d); // TODO support sending scheduled messages
|
||||
m->message_id =
|
||||
is_scheduled ? get_next_yet_unsent_scheduled_message_id(d, m->date) : get_next_yet_unsent_message_id(d);
|
||||
m->random_y = get_random_y(m->message_id);
|
||||
if (!is_scheduled) {
|
||||
m->date = now;
|
||||
@ -28271,9 +28285,13 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
||||
}
|
||||
auto now = G()->unix_time();
|
||||
for (auto &m : messages) {
|
||||
m->message_id = get_next_yet_unsent_message_id(to_dialog); // TODO support sending scheduled messages
|
||||
bool is_scheduled = m->message_id.is_scheduled();
|
||||
m->message_id = is_scheduled ? get_next_yet_unsent_scheduled_message_id(to_dialog, m->date)
|
||||
: get_next_yet_unsent_message_id(to_dialog);
|
||||
m->random_y = get_random_y(m->message_id);
|
||||
m->date = now;
|
||||
if (!is_scheduled) {
|
||||
m->date = now;
|
||||
}
|
||||
m->content = dup_message_content(td_, to_dialog_id, m->content.get(), true);
|
||||
m->have_previous = true;
|
||||
m->have_next = true;
|
||||
|
@ -1311,7 +1311,9 @@ class MessagesManager : public Actor {
|
||||
public:
|
||||
MessagesIterator() = default;
|
||||
|
||||
MessagesIterator(Dialog *d, MessageId message_id) : MessagesIteratorBase(d->messages.get(), message_id) {
|
||||
MessagesIterator(Dialog *d, MessageId message_id)
|
||||
: MessagesIteratorBase(message_id.is_scheduled() ? d->scheduled_messages.get() : d->messages.get(),
|
||||
message_id) {
|
||||
}
|
||||
|
||||
Message *operator*() const {
|
||||
@ -1323,7 +1325,9 @@ class MessagesManager : public Actor {
|
||||
public:
|
||||
MessagesConstIterator() = default;
|
||||
|
||||
MessagesConstIterator(const Dialog *d, MessageId message_id) : MessagesIteratorBase(d->messages.get(), message_id) {
|
||||
MessagesConstIterator(const Dialog *d, MessageId message_id)
|
||||
: MessagesIteratorBase(message_id.is_scheduled() ? d->scheduled_messages.get() : d->messages.get(),
|
||||
message_id) {
|
||||
}
|
||||
|
||||
const Message *operator*() const {
|
||||
@ -2271,6 +2275,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
static MessageId get_next_yet_unsent_message_id(Dialog *d);
|
||||
|
||||
static MessageId get_next_yet_unsent_scheduled_message_id(const Dialog *d, int32 date);
|
||||
|
||||
bool add_recently_found_dialog_internal(DialogId dialog_id);
|
||||
|
||||
bool remove_recently_found_dialog_internal(DialogId dialog_id);
|
||||
|
Reference in New Issue
Block a user