Add mini-diffs and change the difference transmission frequency.

This commit is contained in:
2025-12-02 18:06:23 -05:00
parent 383ed25453
commit 27b5ce7ef4
4 changed files with 54 additions and 28 deletions

View File

@@ -201,7 +201,7 @@ public:
world_to_synchronous(); world_to_synchronous();
try { try {
DebugCollector dbc(""); DebugCollector dbc("");
int64_t nactor = world_->patch_everything(sb, &dbc); int64_t nactor = world_->patch(sb, &dbc);
if (nactor != actor_id_) change_actor_id(nactor); if (nactor != actor_id_) change_actor_id(nactor);
dbc.dump(stdostream()); dbc.dump(stdostream());
} catch (const StreamException &sexcept) { } catch (const StreamException &sexcept) {

View File

@@ -14,7 +14,8 @@ public:
int64_t actor_id_; int64_t actor_id_;
SharedChannel channel_; SharedChannel channel_;
UniqueWorld sync_; UniqueWorld sync_;
double last_diff_; double last_full_diff_;
double last_mini_diff_;
bool async_diff_; bool async_diff_;
}; };
using UniqueClient = std::unique_ptr<Client>; using UniqueClient = std::unique_ptr<Client>;
@@ -117,13 +118,13 @@ public:
client.reset(); client.reset();
} }
void send_diffs(UniqueClient &client) { void send_diffs(UniqueClient &client, bool full) {
StreamBuffer *sb = client->channel_->out(); StreamBuffer *sb = client->channel_->out();
sb->write_uint8(util::MSG_DIFF); sb->write_uint8(util::MSG_DIFF);
sb->write_uint32(0); sb->write_uint32(0);
int64_t tw_1 = sb->total_writes(); int64_t tw_1 = sb->total_writes();
//stdostream() << "Sending diffs to client " << client->actor_id_ << std::endl; //stdostream() << "Sending diffs to client " << client->actor_id_ << std::endl;
client->sync_->diff_everything(client->actor_id_, master_.get(), sb); client->sync_->diff(client->actor_id_, full, master_.get(), sb);
int64_t tw_2 = sb->total_writes(); int64_t tw_2 = sb->total_writes();
sb->overwrite_int32(tw_1, tw_2 - tw_1); sb->overwrite_int32(tw_1, tw_2 - tw_1);
} }
@@ -218,7 +219,8 @@ public:
// TODO: initialize the login actor on the master. // TODO: initialize the login actor on the master.
client->channel_ = std::move(chan); client->channel_ = std::move(chan);
client->async_diff_ = true; client->async_diff_ = true;
client->last_diff_ = -100.0; client->last_full_diff_ = -100.0;
client->last_mini_diff_ = -100.0;
client->sync_.reset(new World(WORLD_TYPE_PREDICTIVE)); client->sync_.reset(new World(WORLD_TYPE_PREDICTIVE));
// This login actor is never used, it is just to preserve the invariant that // This login actor is never used, it is just to preserve the invariant that
// the client model and the server synchronous model are identical. // the client model and the server synchronous model are identical.
@@ -254,11 +256,26 @@ public:
if (client == nullptr) continue; if (client == nullptr) continue;
// Possibly send a diff. // Possibly send a diff.
double diffdelay = 5.0; // Currently, it's configured to send about
if (client->async_diff_) diffdelay = 0.1; // ten mini-diffs per second, and two full diffs
if (clock >= client->last_diff_ + diffdelay) { // per second. It actually only considers sending
send_diffs(client); // a full diff if it already has decided to send
client->last_diff_ = clock; // a mini diff.
double mini_delay = 0.1;
double full_delay = 0.45;
if (client->async_diff_) {
mini_delay = 0.05;
full_delay = 0.1;
}
if (clock >= client->last_mini_diff_ + mini_delay) {
if (clock >= client->last_full_diff_ + full_delay) {
send_diffs(client, true);
client->last_full_diff_ = clock;
client->last_mini_diff_ = clock;
} else {
send_diffs(client, false);
client->last_mini_diff_ = clock;
}
client->async_diff_ = false; client->async_diff_ = false;
} }
} }

View File

@@ -357,23 +357,29 @@ void World::diff_globals(World *master, StreamBuffer *sb) {
assert(tsb.empty()); assert(tsb.empty());
} }
int64_t World::patch_everything(StreamBuffer *sb, DebugCollector *dbc) { int64_t World::patch(StreamBuffer *sb, DebugCollector *dbc) {
DebugBlock dbb(dbc, "patch_everything"); DebugBlock dbb(dbc, "patch");
int64_t actor_id = patch_actor(sb, dbc); int64_t actor_id = patch_actor(sb, dbc);
patch_visible(sb, dbc); patch_visible(sb, dbc);
patch_luatabs(sb, dbc); bool full = sb->read_bool();
patch_tanclass(sb, dbc); if (full) {
patch_source(sb, dbc); patch_luatabs(sb, dbc);
patch_globals(sb, dbc); patch_tanclass(sb, dbc);
patch_source(sb, dbc);
patch_globals(sb, dbc);
}
return actor_id; return actor_id;
} }
void World::diff_everything(int64_t actor_id, World *master, StreamBuffer *sb) { void World::diff(int64_t actor_id, bool full, World *master, StreamBuffer *sb) {
diff_actor(actor_id, master, sb); diff_actor(actor_id, master, sb);
util::IdVector visible = get_visible_union(actor_id, master); util::IdVector visible = get_visible_union(actor_id, master);
diff_visible(visible, master, sb); diff_visible(visible, master, sb);
diff_luatabs(actor_id, master, sb); sb->write_bool(full);
diff_tanclass(actor_id, master, sb); if (full) {
diff_source(master, sb); diff_luatabs(actor_id, master, sb);
diff_globals(master, sb); diff_tanclass(actor_id, master, sb);
diff_source(master, sb);
diff_globals(master, sb);
}
} }

View File

@@ -497,7 +497,7 @@ public:
public: public:
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// //
// world-difftab: Nonrecursive table comparison // difference transmission internals related to table comparison
// //
// These routines compare tables in the master lua to the corresponding // These routines compare tables in the master lua to the corresponding
// tables in the synchronous lua. This is a nonrecursive process, because // tables in the synchronous lua. This is a nonrecursive process, because
@@ -514,10 +514,9 @@ public:
void patch_tangible_classes(StreamBuffer *sb, DebugCollector *dbc); void patch_tangible_classes(StreamBuffer *sb, DebugCollector *dbc);
void diff_tangible_classes(const IdVector &basis, lua_State *master, StreamBuffer *sb); void diff_tangible_classes(const IdVector &basis, lua_State *master, StreamBuffer *sb);
public:
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// //
// Difference transmission // Difference transmission internals
// //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@@ -540,11 +539,15 @@ public:
void patch_globals(StreamBuffer *sb, DebugCollector *dbc); void patch_globals(StreamBuffer *sb, DebugCollector *dbc);
void diff_globals(World *master, StreamBuffer *sb); void diff_globals(World *master, StreamBuffer *sb);
// This is the main entry point for difference transmission. ///////////////////////////////////////////////////////////
// //
int64_t patch_everything(StreamBuffer *sb, DebugCollector *dbc); // Difference transmission entry point.
void diff_everything(int64_t actor, World *master, StreamBuffer *sb); //
///////////////////////////////////////////////////////////
int64_t patch(StreamBuffer *sb, DebugCollector *dbc);
void diff(int64_t actor, bool full, World *master, StreamBuffer *sb);
public: public:
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////