diff --git a/examples~/quickstart/client/module_bindings/IdentityConnectedReducer.cs b/examples~/quickstart/client/module_bindings/IdentityConnectedReducer.cs
new file mode 100644
index 00000000..36fd4604
--- /dev/null
+++ b/examples~/quickstart/client/module_bindings/IdentityConnectedReducer.cs
@@ -0,0 +1,17 @@
+// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
+// WILL NOT BE SAVED. MODIFY TABLES IN RUST INSTEAD.
+//
+
+#nullable enable
+
+using System;
+using SpacetimeDB;
+
+namespace SpacetimeDB.Types
+{
+ [SpacetimeDB.Type]
+ public partial class IdentityConnected : IReducerArgs
+ {
+ uint IReducerArgs.ReducerIndex => 0;
+ }
+}
diff --git a/examples~/quickstart/client/module_bindings/IdentityDisconnectedReducer.cs b/examples~/quickstart/client/module_bindings/IdentityDisconnectedReducer.cs
new file mode 100644
index 00000000..79ba1703
--- /dev/null
+++ b/examples~/quickstart/client/module_bindings/IdentityDisconnectedReducer.cs
@@ -0,0 +1,17 @@
+// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
+// WILL NOT BE SAVED. MODIFY TABLES IN RUST INSTEAD.
+//
+
+#nullable enable
+
+using System;
+using SpacetimeDB;
+
+namespace SpacetimeDB.Types
+{
+ [SpacetimeDB.Type]
+ public partial class IdentityDisconnected : IReducerArgs
+ {
+ uint IReducerArgs.ReducerIndex => 1;
+ }
+}
diff --git a/examples~/quickstart/client/module_bindings/InitReducer.cs b/examples~/quickstart/client/module_bindings/InitReducer.cs
new file mode 100644
index 00000000..a8ed3e04
--- /dev/null
+++ b/examples~/quickstart/client/module_bindings/InitReducer.cs
@@ -0,0 +1,17 @@
+// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
+// WILL NOT BE SAVED. MODIFY TABLES IN RUST INSTEAD.
+//
+
+#nullable enable
+
+using System;
+using SpacetimeDB;
+
+namespace SpacetimeDB.Types
+{
+ [SpacetimeDB.Type]
+ public partial class Init : IReducerArgs
+ {
+ uint IReducerArgs.ReducerIndex => 2;
+ }
+}
diff --git a/examples~/quickstart/client/module_bindings/SendMessageReducer.cs b/examples~/quickstart/client/module_bindings/SendMessageReducer.cs
index 15106671..68c6845c 100644
--- a/examples~/quickstart/client/module_bindings/SendMessageReducer.cs
+++ b/examples~/quickstart/client/module_bindings/SendMessageReducer.cs
@@ -12,7 +12,7 @@ namespace SpacetimeDB.Types
[SpacetimeDB.Type]
public partial class SendMessage : IReducerArgs
{
- string IReducerArgs.ReducerName => "send_message";
+ uint IReducerArgs.ReducerIndex => 3;
public string Text = "";
}
diff --git a/examples~/quickstart/client/module_bindings/SetNameReducer.cs b/examples~/quickstart/client/module_bindings/SetNameReducer.cs
index 83a0b728..d17c24d7 100644
--- a/examples~/quickstart/client/module_bindings/SetNameReducer.cs
+++ b/examples~/quickstart/client/module_bindings/SetNameReducer.cs
@@ -12,7 +12,7 @@ namespace SpacetimeDB.Types
[SpacetimeDB.Type]
public partial class SetName : IReducerArgs
{
- string IReducerArgs.ReducerName => "set_name";
+ uint IReducerArgs.ReducerIndex => 4;
public string Name = "";
}
diff --git a/examples~/quickstart/client/module_bindings/_Globals/SpacetimeDBClient.cs b/examples~/quickstart/client/module_bindings/_Globals/SpacetimeDBClient.cs
index 726f56d0..078fc09c 100644
--- a/examples~/quickstart/client/module_bindings/_Globals/SpacetimeDBClient.cs
+++ b/examples~/quickstart/client/module_bindings/_Globals/SpacetimeDBClient.cs
@@ -65,6 +65,54 @@ public sealed class RemoteReducers : RemoteBase
{
internal RemoteReducers(DbConnection conn, SetReducerFlags SetReducerFlags) : base(conn) { this.SetCallReducerFlags = SetReducerFlags; }
internal readonly SetReducerFlags SetCallReducerFlags;
+ public delegate void IdentityConnectedHandler(EventContext ctx);
+ public event IdentityConnectedHandler? OnIdentityConnected;
+
+ public void IdentityConnected()
+ {
+ conn.InternalCallReducer(new IdentityConnected { }, this.SetCallReducerFlags.IdentityConnectedFlags);
+ }
+
+ public bool InvokeIdentityConnected(EventContext ctx, IdentityConnected args)
+ {
+ if (OnIdentityConnected == null) return false;
+ OnIdentityConnected(
+ ctx
+ );
+ return true;
+ }
+ public delegate void IdentityDisconnectedHandler(EventContext ctx);
+ public event IdentityDisconnectedHandler? OnIdentityDisconnected;
+
+ public void IdentityDisconnected()
+ {
+ conn.InternalCallReducer(new IdentityDisconnected { }, this.SetCallReducerFlags.IdentityDisconnectedFlags);
+ }
+
+ public bool InvokeIdentityDisconnected(EventContext ctx, IdentityDisconnected args)
+ {
+ if (OnIdentityDisconnected == null) return false;
+ OnIdentityDisconnected(
+ ctx
+ );
+ return true;
+ }
+ public delegate void InitHandler(EventContext ctx);
+ public event InitHandler? OnInit;
+
+ public void Init()
+ {
+ conn.InternalCallReducer(new Init { }, this.SetCallReducerFlags.InitFlags);
+ }
+
+ public bool InvokeInit(EventContext ctx, Init args)
+ {
+ if (OnInit == null) return false;
+ OnInit(
+ ctx
+ );
+ return true;
+ }
public delegate void SendMessageHandler(EventContext ctx, string text);
public event SendMessageHandler? OnSendMessage;
@@ -104,6 +152,12 @@ public bool InvokeSetName(EventContext ctx, SetName args)
public sealed class SetReducerFlags
{
internal SetReducerFlags() { }
+ internal CallReducerFlags IdentityConnectedFlags;
+ public void IdentityConnected(CallReducerFlags flags) { this.IdentityConnectedFlags = flags; }
+ internal CallReducerFlags IdentityDisconnectedFlags;
+ public void IdentityDisconnected(CallReducerFlags flags) { this.IdentityDisconnectedFlags = flags; }
+ internal CallReducerFlags InitFlags;
+ public void Init(CallReducerFlags flags) { this.InitFlags = flags; }
internal CallReducerFlags SendMessageFlags;
public void SendMessage(CallReducerFlags flags) { this.SendMessageFlags = flags; }
internal CallReducerFlags SetNameFlags;
@@ -126,11 +180,12 @@ internal EventContext(DbConnection conn, Event reducerEvent) : base(con
[Type]
public partial record Reducer : TaggedEnum<(
+ IdentityConnected IdentityConnected,
+ IdentityDisconnected IdentityDisconnected,
+ Init Init,
SendMessage SendMessage,
SetName SetName,
- Unit StdbNone,
- Unit StdbIdentityConnected,
- Unit StdbIdentityDisconnected
+ Unit StdbNone
)>;
public class DbConnection : DbConnectionBase
{
@@ -143,21 +198,20 @@ public DbConnection()
SetReducerFlags = new();
Reducers = new(this, this.SetReducerFlags);
- clientDB.AddTable("message", Db.Message);
- clientDB.AddTable("user", Db.User);
+ clientDB.AddTable(0, Db.Message);
+ clientDB.AddTable(1, Db.User);
}
- protected override Reducer ToReducer(TransactionUpdate update)
+ protected override Reducer ToReducer(uint reducerIdx, TransactionUpdate update)
{
var encodedArgs = update.ReducerCall.Args;
- return update.ReducerCall.ReducerName switch
- {
- "send_message" => new Reducer.SendMessage(BSATNHelpers.Decode(encodedArgs)),
- "set_name" => new Reducer.SetName(BSATNHelpers.Decode(encodedArgs)),
- "" => new Reducer.StdbNone(default),
- "__identity_connected__" => new Reducer.StdbIdentityConnected(default),
- "__identity_disconnected__" => new Reducer.StdbIdentityDisconnected(default),
- "" => new Reducer.StdbNone(default),
+ return reducerIdx switch {
+ 0 => new Reducer.IdentityConnected(BSATNHelpers.Decode(encodedArgs)),
+ 1 => new Reducer.IdentityDisconnected(BSATNHelpers.Decode(encodedArgs)),
+ 2 => new Reducer.Init(BSATNHelpers.Decode(encodedArgs)),
+ 3 => new Reducer.SendMessage(BSATNHelpers.Decode(encodedArgs)),
+ 4 => new Reducer.SetName(BSATNHelpers.Decode(encodedArgs)),
+ 4294967295 => new Reducer.StdbNone(default),
var reducer => throw new ArgumentOutOfRangeException("Reducer", $"Unknown reducer {reducer}")
};
}
@@ -168,13 +222,13 @@ protected override IEventContext ToEventContext(Event reducerEvent) =>
protected override bool Dispatch(IEventContext context, Reducer reducer)
{
var eventContext = (EventContext)context;
- return reducer switch
- {
+ return reducer switch {
+ Reducer.IdentityConnected(var args) => Reducers.InvokeIdentityConnected(eventContext, args),
+ Reducer.IdentityDisconnected(var args) => Reducers.InvokeIdentityDisconnected(eventContext, args),
+ Reducer.Init(var args) => Reducers.InvokeInit(eventContext, args),
Reducer.SendMessage(var args) => Reducers.InvokeSendMessage(eventContext, args),
Reducer.SetName(var args) => Reducers.InvokeSetName(eventContext, args),
- Reducer.StdbNone or
- Reducer.StdbIdentityConnected or
- Reducer.StdbIdentityDisconnected => true,
+ Reducer.StdbNone => true,
_ => throw new ArgumentOutOfRangeException("Reducer", $"Unknown reducer {reducer}")
};
}
diff --git a/src/ClientCache.cs b/src/ClientCache.cs
index 9e01e327..430e287c 100644
--- a/src/ClientCache.cs
+++ b/src/ClientCache.cs
@@ -12,29 +12,29 @@ public class ClientCache
{
private readonly IDbConnection conn;
- private readonly Dictionary tables = new();
+ private readonly Dictionary tables = new();
public ClientCache(IDbConnection conn) => this.conn = conn;
- public void AddTable(string name, IRemoteTableHandle table)
+ public void AddTable(uint tableIdx, IRemoteTableHandle table)
where Row : IDatabaseRow, new()
{
- if (!tables.TryAdd(name, table))
+ if (!tables.TryAdd(tableIdx, table))
{
- Log.Error($"Table with name already exists: {name}");
+ Log.Error($"Table with index already exists: {tableIdx}");
}
- table.Initialize(name, conn);
+ table.Initialize(tableIdx, conn);
}
- internal IRemoteTableHandle? GetTable(string name)
+ internal IRemoteTableHandle? GetTable(uint tableIdx)
{
- if (tables.TryGetValue(name, out var table))
+ if (tables.TryGetValue(tableIdx, out var table))
{
return table;
}
- Log.Error($"We don't know that this table is: {name}");
+ Log.Error($"We don't know that this table is: {tableIdx}");
return null;
}
diff --git a/src/Event.cs b/src/Event.cs
index b637e698..29cc844a 100644
--- a/src/Event.cs
+++ b/src/Event.cs
@@ -6,7 +6,7 @@ public interface IEventContext { }
public interface IReducerArgs : BSATN.IStructuralReadWrite
{
- string ReducerName { get; }
+ uint ReducerIndex { get; }
}
[Type]
diff --git a/src/SpacetimeDB/ClientApi/AfterConnecting.cs b/src/SpacetimeDB/ClientApi/AfterConnecting.cs
new file mode 100644
index 00000000..a141c3f0
--- /dev/null
+++ b/src/SpacetimeDB/ClientApi/AfterConnecting.cs
@@ -0,0 +1,35 @@
+#nullable enable
+
+using System;
+using SpacetimeDB;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace SpacetimeDB.ClientApi
+{
+ [SpacetimeDB.Type]
+ [DataContract]
+ public partial class AfterConnecting
+ {
+ [DataMember(Name = "identity_token")]
+ public SpacetimeDB.ClientApi.IdentityToken IdentityToken;
+ [DataMember(Name = "ids_to_names")]
+ public SpacetimeDB.ClientApi.IdsToNames IdsToNames;
+
+ public AfterConnecting(
+ SpacetimeDB.ClientApi.IdentityToken IdentityToken,
+ SpacetimeDB.ClientApi.IdsToNames IdsToNames
+ )
+ {
+ this.IdentityToken = IdentityToken;
+ this.IdsToNames = IdsToNames;
+ }
+
+ public AfterConnecting()
+ {
+ this.IdentityToken = new();
+ this.IdsToNames = new();
+ }
+
+ }
+}
diff --git a/src/SpacetimeDB/ClientApi/CallReducer.cs b/src/SpacetimeDB/ClientApi/CallReducer.cs
index 212d9bb3..be60a49a 100644
--- a/src/SpacetimeDB/ClientApi/CallReducer.cs
+++ b/src/SpacetimeDB/ClientApi/CallReducer.cs
@@ -15,8 +15,8 @@ namespace SpacetimeDB.ClientApi
[DataContract]
public partial class CallReducer
{
- [DataMember(Name = "reducer")]
- public string Reducer;
+ [DataMember(Name = "reducer_id")]
+ public uint ReducerId;
[DataMember(Name = "args")]
public byte[] Args;
[DataMember(Name = "request_id")]
@@ -25,13 +25,13 @@ public partial class CallReducer
public byte Flags;
public CallReducer(
- string Reducer,
+ uint ReducerId,
byte[] Args,
uint RequestId,
byte Flags
)
{
- this.Reducer = Reducer;
+ this.ReducerId = ReducerId;
this.Args = Args;
this.RequestId = RequestId;
this.Flags = Flags;
@@ -39,7 +39,6 @@ byte Flags
public CallReducer()
{
- this.Reducer = "";
this.Args = Array.Empty();
}
diff --git a/src/SpacetimeDB/ClientApi/IdsToNames.cs b/src/SpacetimeDB/ClientApi/IdsToNames.cs
new file mode 100644
index 00000000..f9f2e0f4
--- /dev/null
+++ b/src/SpacetimeDB/ClientApi/IdsToNames.cs
@@ -0,0 +1,45 @@
+#nullable enable
+
+using System;
+using SpacetimeDB;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace SpacetimeDB.ClientApi
+{
+ [SpacetimeDB.Type]
+ [DataContract]
+ public partial class IdsToNames
+ {
+ [DataMember(Name = "reducer_ids")]
+ public System.Collections.Generic.List ReducerIds;
+ [DataMember(Name = "reducer_names")]
+ public System.Collections.Generic.List ReducerNames;
+ [DataMember(Name = "table_ids")]
+ public System.Collections.Generic.List TableIds;
+ [DataMember(Name = "table_names")]
+ public System.Collections.Generic.List TableNames;
+
+ public IdsToNames(
+ System.Collections.Generic.List ReducerIds,
+ System.Collections.Generic.List ReducerNames,
+ System.Collections.Generic.List TableIds,
+ System.Collections.Generic.List TableNames
+ )
+ {
+ this.ReducerIds = ReducerIds;
+ this.ReducerNames = ReducerNames;
+ this.TableIds = TableIds;
+ this.TableNames = TableNames;
+ }
+
+ public IdsToNames()
+ {
+ ReducerIds = new();
+ ReducerNames = new();
+ TableIds = new();
+ TableNames = new();
+ }
+
+ }
+}
diff --git a/src/SpacetimeDB/ClientApi/OneOffTable.cs b/src/SpacetimeDB/ClientApi/OneOffTable.cs
index fe667b18..e7d9f5a9 100644
--- a/src/SpacetimeDB/ClientApi/OneOffTable.cs
+++ b/src/SpacetimeDB/ClientApi/OneOffTable.cs
@@ -15,23 +15,22 @@ namespace SpacetimeDB.ClientApi
[DataContract]
public partial class OneOffTable
{
- [DataMember(Name = "table_name")]
- public string TableName;
+ [DataMember(Name = "table_id")]
+ public uint TableId;
[DataMember(Name = "rows")]
public SpacetimeDB.ClientApi.BsatnRowList Rows;
public OneOffTable(
- string TableName,
+ uint TableId,
SpacetimeDB.ClientApi.BsatnRowList Rows
)
{
- this.TableName = TableName;
+ this.TableId = TableId;
this.Rows = Rows;
}
public OneOffTable()
{
- this.TableName = "";
this.Rows = new();
}
diff --git a/src/SpacetimeDB/ClientApi/ReducerCallInfo.cs b/src/SpacetimeDB/ClientApi/ReducerCallInfo.cs
index f8acaffd..665112f2 100644
--- a/src/SpacetimeDB/ClientApi/ReducerCallInfo.cs
+++ b/src/SpacetimeDB/ClientApi/ReducerCallInfo.cs
@@ -15,8 +15,6 @@ namespace SpacetimeDB.ClientApi
[DataContract]
public partial class ReducerCallInfo
{
- [DataMember(Name = "reducer_name")]
- public string ReducerName;
[DataMember(Name = "reducer_id")]
public uint ReducerId;
[DataMember(Name = "args")]
@@ -25,13 +23,11 @@ public partial class ReducerCallInfo
public uint RequestId;
public ReducerCallInfo(
- string ReducerName,
uint ReducerId,
byte[] Args,
uint RequestId
)
{
- this.ReducerName = ReducerName;
this.ReducerId = ReducerId;
this.Args = Args;
this.RequestId = RequestId;
@@ -39,7 +35,6 @@ uint RequestId
public ReducerCallInfo()
{
- this.ReducerName = "";
this.Args = Array.Empty();
}
diff --git a/src/SpacetimeDB/ClientApi/ServerMessage.cs b/src/SpacetimeDB/ClientApi/ServerMessage.cs
index f66fdd98..d7b9f9a8 100644
--- a/src/SpacetimeDB/ClientApi/ServerMessage.cs
+++ b/src/SpacetimeDB/ClientApi/ServerMessage.cs
@@ -14,7 +14,7 @@ public partial record ServerMessage : SpacetimeDB.TaggedEnum<(
SpacetimeDB.ClientApi.InitialSubscription InitialSubscription,
SpacetimeDB.ClientApi.TransactionUpdate TransactionUpdate,
SpacetimeDB.ClientApi.TransactionUpdateLight TransactionUpdateLight,
- SpacetimeDB.ClientApi.IdentityToken IdentityToken,
+ SpacetimeDB.ClientApi.AfterConnecting AfterConnecting,
SpacetimeDB.ClientApi.OneOffQueryResponse OneOffQueryResponse
)>;
}
diff --git a/src/SpacetimeDB/ClientApi/TableUpdate.cs b/src/SpacetimeDB/ClientApi/TableUpdate.cs
index d3265065..157c440c 100644
--- a/src/SpacetimeDB/ClientApi/TableUpdate.cs
+++ b/src/SpacetimeDB/ClientApi/TableUpdate.cs
@@ -17,8 +17,6 @@ public partial class TableUpdate
{
[DataMember(Name = "table_id")]
public uint TableId;
- [DataMember(Name = "table_name")]
- public string TableName;
[DataMember(Name = "num_rows")]
public ulong NumRows;
[DataMember(Name = "updates")]
@@ -26,20 +24,17 @@ public partial class TableUpdate
public TableUpdate(
uint TableId,
- string TableName,
ulong NumRows,
System.Collections.Generic.List Updates
)
{
this.TableId = TableId;
- this.TableName = TableName;
this.NumRows = NumRows;
this.Updates = Updates;
}
public TableUpdate()
{
- this.TableName = "";
this.Updates = new();
}
diff --git a/src/SpacetimeDBClient.cs b/src/SpacetimeDBClient.cs
index b3cb22e5..f588b7b2 100644
--- a/src/SpacetimeDBClient.cs
+++ b/src/SpacetimeDBClient.cs
@@ -98,6 +98,7 @@ public interface IDbConnection
void Disconnect();
internal Task RemoteQuery(string query) where T : IDatabaseRow, new();
+ string TableName(uint tableIdx);
}
public abstract class DbConnectionBase : IDbConnection
@@ -147,7 +148,7 @@ struct DbOp
private bool connectionClosed;
protected readonly ClientCache clientDB;
- protected abstract Reducer ToReducer(TransactionUpdate update);
+ protected abstract Reducer ToReducer(uint reducerIdx, TransactionUpdate update);
protected abstract IEventContext ToEventContext(Event reducerEvent);
private readonly Dictionary> waitingOneOffQueries = new();
@@ -156,6 +157,29 @@ struct DbOp
private readonly Thread networkMessageProcessThread;
public readonly Stats stats = new();
+ private Dictionary reducerIdToIdx = new();
+ private List reducerIdxToId = new();
+ private List reducerIdxToName = new();
+ private Dictionary tableIdToIdx = new();
+ private List tableIdxToName = new();
+ private void InitIds(IdsToNames idsToNames)
+ {
+ reducerIdxToId = idsToNames.ReducerIds;
+ reducerIdxToName = idsToNames.ReducerNames;
+ tableIdxToName = idsToNames.TableNames;
+
+ for (int reducerIdx = 0; reducerIdx < reducerIdxToId.Count; reducerIdx++)
+ {
+ reducerIdToIdx.Add(reducerIdxToId[reducerIdx], (uint)reducerIdx);
+ }
+ for (int tableIdx = 0; tableIdx < idsToNames.TableIds.Count; tableIdx++)
+ {
+ tableIdToIdx.Add(idsToNames.TableIds[tableIdx], (uint)tableIdx);
+ }
+ }
+ string IDbConnection.TableName(uint tableIdx) => tableIdxToName[(int)tableIdx];
+ private string TableIdToName(uint tableId) => tableIdxToName[(int)tableIdToIdx[tableId]];
+
protected DbConnectionBase()
{
clientDB = new(this);
@@ -342,11 +366,11 @@ void PreProcessMessages()
{
foreach (var update in updates.Tables)
{
- var tableName = update.TableName;
- var table = clientDB.GetTable(tableName);
+ var tableIdx = tableIdToIdx[update.TableId];
+ var table = clientDB.GetTable(tableIdx);
if (table == null)
{
- Log.Error($"Unknown table name: {tableName}");
+ Log.Error($"Unknown table name: {update.TableId}");
continue;
}
@@ -437,7 +461,7 @@ List PreProcessDatabaseUpdate(DatabaseUpdate updates)
{
if ((op.insert is not null && oldOp.insert is not null) || (op.delete is not null && oldOp.delete is not null))
{
- Log.Warn($"Update with the same primary key was applied multiple times! tableName={update.TableName}");
+ Log.Warn($"Update with the same primary key was applied multiple times! tableName={TableIdToName(update.TableId)}");
// TODO(jdetter): Is this a correctable error? This would be a major error on the
// SpacetimeDB side.
continue;
@@ -472,7 +496,7 @@ List PreProcessDatabaseUpdate(DatabaseUpdate updates)
{
if ((op.insert is not null && oldOp.insert is not null) || (op.delete is not null && oldOp.delete is not null))
{
- Log.Warn($"Update with the same primary key was applied multiple times! tableName={update.TableName}");
+ Log.Warn($"Update with the same primary key was applied multiple times! tableName={TableIdToName(update.TableId)}");
// TODO(jdetter): Is this a correctable error? This would be a major error on the
// SpacetimeDB side.
continue;
@@ -538,6 +562,7 @@ PreProcessedMessage PreProcessMessage(UnprocessedMessage unprocessed)
// Convert the generic event arguments in to a domain specific event object
try
{
+ var reducerIdx = reducerIdToIdx[transactionUpdate.ReducerCall.ReducerId];
reducerEvent = new(
DateTimeOffset.FromUnixTimeMilliseconds((long)transactionUpdate.Timestamp.Microseconds / 1000),
transactionUpdate.Status switch
@@ -550,7 +575,7 @@ PreProcessedMessage PreProcessMessage(UnprocessedMessage unprocessed)
transactionUpdate.CallerIdentity,
transactionUpdate.CallerAddress,
transactionUpdate.EnergyQuantaUsed.Quanta,
- ToReducer(transactionUpdate));
+ ToReducer(reducerIdx, transactionUpdate));
}
catch (Exception e)
{
@@ -565,7 +590,8 @@ PreProcessedMessage PreProcessMessage(UnprocessedMessage unprocessed)
case ServerMessage.TransactionUpdateLight(var update):
dbOps = PreProcessDatabaseUpdate(update.Update);
break;
- case ServerMessage.IdentityToken(var identityToken):
+ case ServerMessage.AfterConnecting(var afterConnecting):
+ InitIds(afterConnecting.IdsToNames);
break;
case ServerMessage.OneOffQueryResponse(var resp):
PreProcessOneOffQuery(resp);
@@ -781,7 +807,7 @@ private void OnMessageProcessComplete(PreProcessedMessage preProcessed)
case ServerMessage.TransactionUpdate(var transactionUpdate):
{
- var reducer = transactionUpdate.ReducerCall.ReducerName;
+ var reducer = reducerIdxToName[(int)reducerIdToIdx[transactionUpdate.ReducerCall.ReducerId]];
stats.ParseMessageTracker.InsertRequest(timestamp, $"type={nameof(ServerMessage.TransactionUpdate)},reducer={reducer}");
var hostDuration = TimeSpan.FromMilliseconds(transactionUpdate.HostExecutionDurationMicros / 1000.0d);
stats.AllReducersTracker.InsertRequest(hostDuration, $"reducer={reducer}");
@@ -828,9 +854,10 @@ private void OnMessageProcessComplete(PreProcessedMessage preProcessed)
}
break;
}
- case ServerMessage.IdentityToken(var identityToken):
+ case ServerMessage.AfterConnecting(var afterConnecting):
try
{
+ var identityToken = afterConnecting.IdentityToken;
Identity = identityToken.Identity;
onConnect?.Invoke(identityToken.Identity, identityToken.Token);
}
@@ -863,10 +890,14 @@ public void InternalCallReducer(T args, CallReducerFlags flags)
return;
}
+ var reducerIdx = (int)args.ReducerIndex;
+ var reducerId = reducerIdxToId[reducerIdx];
+ var reducerName = reducerIdxToName[reducerIdx];
+
webSocket.Send(new ClientMessage.CallReducer(new CallReducer(
- args.ReducerName,
+ reducerId,
IStructuralReadWrite.ToBytes(args),
- stats.ReducerRequestTracker.StartTrackingRequest(args.ReducerName),
+ stats.ReducerRequestTracker.StartTrackingRequest(reducerName),
(byte)flags
)));
}
@@ -938,11 +969,11 @@ T[] LogAndThrow(string error)
}
var resultTable = result.Tables[0];
- var cacheTable = clientDB.GetTable(resultTable.TableName);
+ var cacheTable = clientDB.GetTable(resultTable.TableId);
if (cacheTable?.ClientTableType != typeof(T))
{
- return LogAndThrow($"Mismatched result type, expected {typeof(T)} but got {resultTable.TableName}");
+ return LogAndThrow($"Mismatched result type, expected {typeof(T)} but got {TableIdToName(resultTable.TableId)}");
}
return BsatnRowListIter(resultTable.Rows)
diff --git a/src/Table.cs b/src/Table.cs
index d3ebf918..127fe84c 100644
--- a/src/Table.cs
+++ b/src/Table.cs
@@ -38,19 +38,19 @@ public interface IRemoteTableHandle
internal void InvokeBeforeDelete(IEventContext context, IDatabaseRow row);
internal void InvokeUpdate(IEventContext context, IDatabaseRow oldRow, IDatabaseRow newRow);
- internal void Initialize(string name, IDbConnection conn);
+ internal void Initialize(uint tableIdx, IDbConnection conn);
}
public abstract class RemoteTableHandle : IRemoteTableHandle
where EventContext : class, IEventContext
where Row : IDatabaseRow, new()
{
- string? name;
+ uint tableIdx;
IDbConnection? conn;
- void IRemoteTableHandle.Initialize(string name, IDbConnection conn)
+ void IRemoteTableHandle.Initialize(uint tableIdx, IDbConnection conn)
{
- this.name = name;
+ this.tableIdx = tableIdx;
this.conn = conn;
}
@@ -106,7 +106,7 @@ bool IRemoteTableHandle.DeleteEntry(byte[] rowBytes)
protected IEnumerable Query(Func filter) => Iter().Where(filter);
public Task RemoteQuery(string query) =>
- conn!.RemoteQuery($"SELECT * FROM {name!} {query}");
+ conn!.RemoteQuery($"SELECT * FROM {conn.TableName(tableIdx)!} {query}");
void IRemoteTableHandle.InvokeInsert(IEventContext context, IDatabaseRow row) =>
OnInsert?.Invoke((EventContext)context, (Row)row);
diff --git a/tests~/SnapshotTests.cs b/tests~/SnapshotTests.cs
index d293c126..9e0cbf06 100644
--- a/tests~/SnapshotTests.cs
+++ b/tests~/SnapshotTests.cs
@@ -96,13 +96,16 @@ public void Exception(Exception e)
}
}
- private static ServerMessage.IdentityToken SampleId(string identity, string token, string address) =>
- new(new()
+ private static IdentityToken SampleId(string identity, string token, string address) =>
+ new()
{
Identity = Identity.From(Convert.FromBase64String(identity)),
Token = token,
Address = Address.From(Convert.FromBase64String(address)) ?? throw new InvalidDataException("address")
- });
+ };
+
+ private static ServerMessage.AfterConnecting SampleHandshake(string identity, string token, string address, IdsToNames idsToNames) =>
+ new(new(SampleId(identity, token, address), idsToNames));
private static ServerMessage.InitialSubscription SampleSubscriptionUpdate(
uint requestId,
@@ -123,7 +126,7 @@ private static ServerMessage.TransactionUpdate SampleTransactionUpdate(
string callerIdentity,
string callerAddress,
uint requestId,
- string reducerName,
+ uint reducerId,
ulong energyQuantaUsed,
ulong hostExecutionDuration,
List updates,
@@ -141,7 +144,7 @@ private static ServerMessage.TransactionUpdate SampleTransactionUpdate(
ReducerCall = new()
{
RequestId = requestId,
- ReducerName = reducerName,
+ ReducerId = reducerId,
Args = args ?? []
},
Status = new UpdateStatus.Committed(new()
@@ -152,13 +155,11 @@ private static ServerMessage.TransactionUpdate SampleTransactionUpdate(
private static TableUpdate SampleUpdate(
uint tableId,
- string tableName,
List inserts,
List deletes
) where T : IStructuralReadWrite => new()
{
TableId = tableId,
- TableName = tableName,
NumRows = (ulong)(inserts.Count + deletes.Count),
Updates = [new CompressableQueryUpdate.Uncompressed(new QueryUpdate(
EncodeRowList(deletes), EncodeRowList(inserts)))]
@@ -190,7 +191,7 @@ private static byte[] Encode(in T value) where T : IStructuralReadWrite
}
private static TableUpdate SampleUserInsert(string identity, string? name, bool online) =>
- SampleUpdate(4097, "user", [new User
+ SampleUpdate(4097, [new User
{
Identity = Identity.From(Convert.FromBase64String(identity)),
Name = name,
@@ -198,7 +199,7 @@ private static TableUpdate SampleUserInsert(string identity, string? name, bool
}], []);
private static TableUpdate SampleUserUpdate(string identity, string? oldName, string? newName, bool oldOnline, bool newOnline) =>
- SampleUpdate(4097, "user", [new User
+ SampleUpdate(4097, [new User
{
Identity = Identity.From(Convert.FromBase64String(identity)),
Name = newName,
@@ -211,7 +212,7 @@ private static TableUpdate SampleUserUpdate(string identity, string? oldName, st
}]);
private static TableUpdate SampleMessage(string identity, ulong sent, string text) =>
- SampleUpdate(4098, "message", [new Message
+ SampleUpdate(4098, [new Message
{
Sender = Identity.From(Convert.FromBase64String(identity)),
Sent = sent,
@@ -219,55 +220,61 @@ private static TableUpdate SampleMessage(string identity, ulong sent, string tex
}], []);
private static ServerMessage[] SampleDump() => [
- SampleId(
+ SampleHandshake(
"j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=",
"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJoZXhfaWRlbnRpdHkiOiI4ZjkwY2M5NGE5OTY4ZGY2ZDI5N2JhYTY2NTAzYTg5M2IxYzM0YjBiMDAyNjhhNTE0ODk4ZGQ5NTRiMGRhMjBiIiwiaWF0IjoxNzE4NDg3NjY4LCJleHAiOm51bGx9.PSn481bLRqtFwIh46nOXDY14X3GKbz8t4K4GmBmz50loU6xzeL7zDdCh1V2cmiQsoGq8Erxg0r_6b6Y5SqKoBA",
- "Vd4dFzcEzhLHJ6uNL8VXFg=="
+ "Vd4dFzcEzhLHJ6uNL8VXFg==",
+ new IdsToNames(
+ [],
+ [],
+ [4097, 4098],
+ ["user", "message"]
+ )
),
SampleSubscriptionUpdate(
1, 366, [SampleUserInsert("j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", null, true)]
),
SampleTransactionUpdate(0, "l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", "Kwmeu5riP20rvCTNbBipLA==",
- 0, "unknown-reducer", 0, 40, [], null
+ 0, 50, 0, 40, [], null
),
SampleTransactionUpdate(
1718487763059031, "l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", "Kwmeu5riP20rvCTNbBipLA==",
- 0, "__identity_connected__", 1957615, 66, [SampleUserInsert("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", null, true)],
+ 0, 0, 1957615, 66, [SampleUserInsert("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", null, true)],
null
),
SampleTransactionUpdate(
1718487768057579, "j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", "Vd4dFzcEzhLHJ6uNL8VXFg==",
- 1, "set_name", 4345615, 70, [SampleUserUpdate("j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", null, "A", true, true)],
+ 1, 4, 4345615, 70, [SampleUserUpdate("j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", null, "A", true, true)],
Encode(new SetName { Name = "A" })
),
SampleTransactionUpdate(
1718487775346381, "l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", "Kwmeu5riP20rvCTNbBipLA==",
- 1, "send_message", 2779615, 57, [SampleMessage("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", 1718487775346381, "Hello, A!")],
+ 1, 3, 2779615, 57, [SampleMessage("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", 1718487775346381, "Hello, A!")],
Encode(new SendMessage { Text = "Hello, A!" })
),
SampleTransactionUpdate(
1718487777307855, "l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", "Kwmeu5riP20rvCTNbBipLA==",
- 2, "set_name", 4268615, 98, [SampleUserUpdate("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", null, "B", true, true)],
+ 2, 4, 4268615, 98, [SampleUserUpdate("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", null, "B", true, true)],
Encode(new SetName { Name = "B" })
),
SampleTransactionUpdate(
1718487783175083, "j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", "Vd4dFzcEzhLHJ6uNL8VXFg==",
- 2, "send_message", 2677615, 40, [SampleMessage("j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", 1718487783175083, "Hello, B!")],
+ 2, 3, 2677615, 40, [SampleMessage("j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", 1718487783175083, "Hello, B!")],
Encode(new SendMessage { Text = "Hello, B!" })
),
SampleTransactionUpdate(
1718487787645364, "l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", "Kwmeu5riP20rvCTNbBipLA==",
- 3, "send_message", 2636615, 28, [SampleMessage("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", 1718487787645364, "Goodbye!")],
+ 3, 3, 2636615, 28, [SampleMessage("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", 1718487787645364, "Goodbye!")],
Encode(new SendMessage { Text = "Goodbye!" })
),
SampleTransactionUpdate(
1718487791901504, "l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", "Kwmeu5riP20rvCTNbBipLA==",
- 0, "__identity_disconnected__", 3595615, 75, [SampleUserUpdate("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", "B", "B", true, false)],
+ 0, 1, 3595615, 75, [SampleUserUpdate("l0qzG1GPRtC1mwr+54q98tv0325gozLc6cNzq4vrzqY=", "B", "B", true, false)],
null
),
SampleTransactionUpdate(
1718487794937841, "j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", "Vd4dFzcEzhLHJ6uNL8VXFg==",
- 3, "send_message", 2636615, 34, [SampleMessage("j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", 1718487794937841, "Goodbye!")],
+ 3, 3, 2636615, 34, [SampleMessage("j5DMlKmWjfbSl7qmZQOok7HDSwsAJopRSJjdlUsNogs=", 1718487794937841, "Goodbye!")],
Encode(new SendMessage { Text = "Goodbye!" })
),
];