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 {
|
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)) {
|
if (send_date <= (1 << 30)) {
|
||||||
LOG(ERROR) << "Scheduled message send date " << send_date << " is in the past";
|
LOG(ERROR) << "Scheduled message send date " << send_date << " is in the past";
|
||||||
return;
|
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";
|
LOG(ERROR) << "Scheduled message ID " << server_message_id.get() << " is invalid";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -46,6 +46,20 @@ MessageType MessageId::get_type() const {
|
|||||||
if (id <= 0 || id > max().get()) {
|
if (id <= 0 || id > max().get()) {
|
||||||
return MessageType::None;
|
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) {
|
if ((id & FULL_TYPE_MASK) == 0) {
|
||||||
return MessageType::Server;
|
return MessageType::Server;
|
||||||
}
|
}
|
||||||
@ -65,14 +79,37 @@ ServerMessageId MessageId::get_server_message_id_force() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageId MessageId::get_next_message_id(MessageType type) 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) {
|
switch (type) {
|
||||||
case MessageType::Server:
|
case MessageType::Server:
|
||||||
|
if (is_server()) {
|
||||||
|
return MessageId(ServerMessageId(get_server_message_id().get() + 1));
|
||||||
|
}
|
||||||
return get_next_server_message_id();
|
return get_next_server_message_id();
|
||||||
case MessageType::Local:
|
|
||||||
return MessageId(((id + TYPE_MASK + 1 - TYPE_LOCAL) & ~TYPE_MASK) + TYPE_LOCAL);
|
|
||||||
case MessageType::YetUnsent:
|
case MessageType::YetUnsent:
|
||||||
return MessageId(((id + TYPE_MASK + 1 - TYPE_YET_UNSENT) & ~TYPE_MASK) + TYPE_YET_UNSENT);
|
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:
|
case MessageType::None:
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
enum class MessageType : int32 { None, Server, Local, YetUnsent };
|
enum class MessageType : int32 { None, Server, YetUnsent, Local };
|
||||||
|
|
||||||
class MessageId {
|
class MessageId {
|
||||||
int64 id = 0;
|
int64 id = 0;
|
||||||
@ -55,7 +55,7 @@ class MessageId {
|
|||||||
: id(static_cast<int64>(server_message_id.get()) << SERVER_ID_SHIFT) {
|
: 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) {
|
explicit constexpr MessageId(int64 message_id) : id(message_id) {
|
||||||
}
|
}
|
||||||
@ -131,6 +131,11 @@ class MessageId {
|
|||||||
return get_scheduled_server_message_id_force();
|
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 {
|
bool operator==(const MessageId &other) const {
|
||||||
return id == other.id;
|
return id == other.id;
|
||||||
}
|
}
|
||||||
|
@ -16901,7 +16901,8 @@ MessagesManager::Message *MessagesManager::get_message_to_send(Dialog *d, Messag
|
|||||||
int32 schedule_date = 0;
|
int32 schedule_date = 0;
|
||||||
bool is_scheduled = schedule_date != 0;
|
bool is_scheduled = schedule_date != 0;
|
||||||
CHECK(d != nullptr);
|
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;
|
DialogId dialog_id = d->dialog_id;
|
||||||
LOG(INFO) << "Create " << message_id << " in " << 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);
|
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) {
|
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();
|
auto dialog_id = full_message_id.get_dialog_id();
|
||||||
Dialog *d = get_dialog(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);
|
// 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()) {
|
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 ||
|
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) {
|
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);
|
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;
|
d->last_assigned_message_id = new_message_id;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new_message_id = MessageId(old_message_id.get() + 1); // trying to not change message place
|
while (get_message_force(d, new_message_id, "fail_send_message") != nullptr ||
|
||||||
if (get_message_force(d, new_message_id, "fail_send_message") != nullptr ||
|
d->deleted_message_ids.count(new_message_id)) {
|
||||||
d->deleted_message_ids.count(new_message_id)) {
|
new_message_id = new_message_id.get_next_message_id(MessageType::Local);
|
||||||
// TODO
|
|
||||||
// new_message_id = get_next_scheduled_local_message_id(d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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) {
|
void MessagesManager::attach_message_to_previous(Dialog *d, MessageId message_id, const char *source) {
|
||||||
CHECK(d != nullptr);
|
CHECK(d != nullptr);
|
||||||
|
CHECK(message_id.is_valid());
|
||||||
MessagesIterator it(d, message_id);
|
MessagesIterator it(d, message_id);
|
||||||
Message *m = *it;
|
Message *m = *it;
|
||||||
CHECK(m != nullptr);
|
CHECK(m != nullptr);
|
||||||
CHECK(m->message_id == message_id);
|
CHECK(m->message_id == message_id);
|
||||||
CHECK(m->message_id.is_valid());
|
|
||||||
LOG_CHECK(m->have_previous) << d->dialog_id << " " << message_id << " " << source;
|
LOG_CHECK(m->have_previous) << d->dialog_id << " " << message_id << " " << source;
|
||||||
--it;
|
--it;
|
||||||
LOG_CHECK(*it != nullptr) << d->dialog_id << " " << message_id << " " << source;
|
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) {
|
void MessagesManager::attach_message_to_next(Dialog *d, MessageId message_id, const char *source) {
|
||||||
CHECK(d != nullptr);
|
CHECK(d != nullptr);
|
||||||
|
CHECK(message_id.is_valid());
|
||||||
MessagesIterator it(d, message_id);
|
MessagesIterator it(d, message_id);
|
||||||
Message *m = *it;
|
Message *m = *it;
|
||||||
CHECK(m != nullptr);
|
CHECK(m != nullptr);
|
||||||
CHECK(m->message_id == message_id);
|
CHECK(m->message_id == message_id);
|
||||||
CHECK(m->message_id.is_valid());
|
|
||||||
LOG_CHECK(m->have_next) << d->dialog_id << " " << message_id << " " << source;
|
LOG_CHECK(m->have_next) << d->dialog_id << " " << message_id << " " << source;
|
||||||
++it;
|
++it;
|
||||||
LOG_CHECK(*it != nullptr) << d->dialog_id << " " << message_id << " " << source;
|
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();
|
auto now = G()->unix_time();
|
||||||
bool is_scheduled = m->message_id.is_scheduled();
|
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);
|
m->random_y = get_random_y(m->message_id);
|
||||||
if (!is_scheduled) {
|
if (!is_scheduled) {
|
||||||
m->date = now;
|
m->date = now;
|
||||||
@ -28271,9 +28285,13 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
|||||||
}
|
}
|
||||||
auto now = G()->unix_time();
|
auto now = G()->unix_time();
|
||||||
for (auto &m : messages) {
|
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->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->content = dup_message_content(td_, to_dialog_id, m->content.get(), true);
|
||||||
m->have_previous = true;
|
m->have_previous = true;
|
||||||
m->have_next = true;
|
m->have_next = true;
|
||||||
|
@ -1311,7 +1311,9 @@ class MessagesManager : public Actor {
|
|||||||
public:
|
public:
|
||||||
MessagesIterator() = default;
|
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 {
|
Message *operator*() const {
|
||||||
@ -1323,7 +1325,9 @@ class MessagesManager : public Actor {
|
|||||||
public:
|
public:
|
||||||
MessagesConstIterator() = default;
|
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 {
|
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_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 add_recently_found_dialog_internal(DialogId dialog_id);
|
||||||
|
|
||||||
bool remove_recently_found_dialog_internal(DialogId dialog_id);
|
bool remove_recently_found_dialog_internal(DialogId dialog_id);
|
||||||
|
Loading…
Reference in New Issue
Block a user