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();
try {
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);
dbc.dump(stdostream());
} catch (const StreamException &sexcept) {

View File

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

View File

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

View File

@@ -497,7 +497,7 @@ 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
// 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 diff_tangible_classes(const IdVector &basis, lua_State *master, StreamBuffer *sb);
public:
///////////////////////////////////////////////////////////
//
// Difference transmission
// Difference transmission internals
//
///////////////////////////////////////////////////////////
@@ -541,10 +540,14 @@ public:
void patch_globals(StreamBuffer *sb, DebugCollector *dbc);
void diff_globals(World *master, StreamBuffer *sb);
// This is the main entry point for difference transmission.
///////////////////////////////////////////////////////////
//
int64_t patch_everything(StreamBuffer *sb, DebugCollector *dbc);
void diff_everything(int64_t actor, World *master, StreamBuffer *sb);
// Difference transmission entry point.
//
///////////////////////////////////////////////////////////
int64_t patch(StreamBuffer *sb, DebugCollector *dbc);
void diff(int64_t actor, bool full, World *master, StreamBuffer *sb);
public:
///////////////////////////////////////////////////////////