Skip to content

Commit 225ab25

Browse files
authored
Lua - use native tables to improve code compatibility (#672)
* Make keys and argv as native lua tables * clean up logic * fix test * make tables readonly * format * improve test * significantly improve coverage * fix dispose logic * correctly wire in number return values from lua to garnet calls * Fix fast-path where set arguments were ignored.
1 parent ad81de1 commit 225ab25

File tree

7 files changed

+252
-118
lines changed

7 files changed

+252
-118
lines changed

benchmark/BDN.benchmark/Resp/RespLuaRunnerStress.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace BDN.benchmark.Resp
1010
public unsafe class RespLuaRunnerStress
1111
{
1212
LuaRunner r1, r2, r3, r4;
13-
readonly string[] keys = ["key1", "key2"];
13+
readonly string[] keys = ["key1"];
1414

1515
[GlobalSetup]
1616
public void GlobalSetup()
@@ -36,7 +36,7 @@ public void GlobalCleanup()
3636

3737
[Benchmark]
3838
public void BasicLua1()
39-
=> r1.RunVoid();
39+
=> r1.Run();
4040

4141
[Benchmark]
4242
public void BasicLua2()

libs/common/RespReadUtils.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ public static bool ReadStringArrayResponseWithLengthHeader(out string[] result,
856856
{
857857
if (*ptr == '$')
858858
{
859-
if (!ReadStringWithLengthHeader(out result[i], ref ptr, end))
859+
if (!ReadStringResponseWithLengthHeader(out result[i], ref ptr, end))
860860
return false;
861861
}
862862
else if (*ptr == '+')

libs/server/ArgSlice/ScratchBufferManager.cs

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ public ArgSlice FormatCommandAsResp(string cmd, object[] args, Lua state)
253253
}
254254
scratchBufferOffset = (int)(ptr - scratchBufferHead);
255255
}
256+
t.Dispose();
256257
}
257258
else if (item is long i)
258259
{

libs/server/Lua/LuaCommands.cs

+71-40
Original file line numberDiff line numberDiff line change
@@ -194,36 +194,72 @@ private unsafe bool ExecuteScript(int count, LuaRunner scriptRunner)
194194
{
195195
try
196196
{
197-
object scriptResult = scriptRunner.Run(count, parseState);
198-
if (scriptResult != null)
197+
var scriptResult = scriptRunner.Run(count, parseState);
198+
WriteObject(scriptResult);
199+
}
200+
catch (LuaScriptException ex)
201+
{
202+
logger?.LogError(ex.InnerException ?? ex, "Error executing Lua script callback");
203+
while (!RespWriteUtils.WriteError("ERR " + (ex.InnerException ?? ex).Message, ref dcurr, dend))
204+
SendAndReset();
205+
return true;
206+
}
207+
catch (Exception ex)
208+
{
209+
logger?.LogError(ex, "Error executing Lua script");
210+
while (!RespWriteUtils.WriteError("ERR " + ex.Message, ref dcurr, dend))
211+
SendAndReset();
212+
return true;
213+
}
214+
return true;
215+
}
216+
217+
void WriteObject(object scriptResult)
218+
{
219+
if (scriptResult != null)
220+
{
221+
if (scriptResult is string s)
199222
{
200-
if (scriptResult is string s)
201-
{
202-
while (!RespWriteUtils.WriteAsciiBulkString(s, ref dcurr, dend))
203-
SendAndReset();
204-
}
205-
else if ((scriptResult as byte?) != null && (byte)scriptResult == 36) //equals to $
206-
{
207-
while (!RespWriteUtils.WriteDirect((byte[])scriptResult, ref dcurr, dend))
208-
SendAndReset();
209-
}
210-
else if (scriptResult as Int64? != null)
211-
{
212-
while (!RespWriteUtils.WriteInteger((Int64)scriptResult, ref dcurr, dend))
213-
SendAndReset();
214-
}
215-
else if (scriptResult as ArgSlice? != null)
223+
while (!RespWriteUtils.WriteAsciiBulkString(s, ref dcurr, dend))
224+
SendAndReset();
225+
}
226+
else if ((scriptResult as byte?) != null && (byte)scriptResult == 36) //equals to $
227+
{
228+
while (!RespWriteUtils.WriteDirect((byte[])scriptResult, ref dcurr, dend))
229+
SendAndReset();
230+
}
231+
else if (scriptResult is bool b)
232+
{
233+
if (b)
216234
{
217-
while (!RespWriteUtils.WriteBulkString(((ArgSlice)scriptResult).ToArray(), ref dcurr, dend))
235+
while (!RespWriteUtils.WriteInteger(1, ref dcurr, dend))
218236
SendAndReset();
219237
}
220-
else if (scriptResult as Object[] != null)
238+
else
221239
{
222-
// Two objects one boolean value and the result from the Lua Call
223-
while (!RespWriteUtils.WriteAsciiBulkString((scriptResult as Object[])[1].ToString().AsSpan(), ref dcurr, dend))
240+
while (!RespWriteUtils.WriteDirect(CmdStrings.RESP_ERRNOTFOUND, ref dcurr, dend))
224241
SendAndReset();
225242
}
226-
else if (scriptResult is LuaTable luaTable)
243+
}
244+
else if (scriptResult is long l)
245+
{
246+
while (!RespWriteUtils.WriteInteger(l, ref dcurr, dend))
247+
SendAndReset();
248+
}
249+
else if (scriptResult is ArgSlice a)
250+
{
251+
while (!RespWriteUtils.WriteBulkString(a.ReadOnlySpan, ref dcurr, dend))
252+
SendAndReset();
253+
}
254+
else if (scriptResult is object[] o)
255+
{
256+
// Two objects one boolean value and the result from the Lua Call
257+
while (!RespWriteUtils.WriteAsciiBulkString(o[1].ToString().AsSpan(), ref dcurr, dend))
258+
SendAndReset();
259+
}
260+
else if (scriptResult is LuaTable luaTable)
261+
{
262+
try
227263
{
228264
var retVal = luaTable["err"];
229265
if (retVal != null)
@@ -241,36 +277,31 @@ private unsafe bool ExecuteScript(int count, LuaRunner scriptRunner)
241277
}
242278
else
243279
{
244-
throw new LuaScriptException("Unknown LuaTable return type", "");
280+
int count = luaTable.Values.Count;
281+
while (!RespWriteUtils.WriteArrayLength(count, ref dcurr, dend))
282+
SendAndReset();
283+
foreach (var value in luaTable.Values)
284+
{
285+
WriteObject(value);
286+
}
245287
}
246288
}
247289
}
248-
else
290+
finally
249291
{
250-
throw new LuaScriptException("Unknown return type", "");
292+
luaTable.Dispose();
251293
}
252294
}
253295
else
254296
{
255-
while (!RespWriteUtils.WriteDirect(CmdStrings.RESP_ERRNOTFOUND, ref dcurr, dend))
256-
SendAndReset();
297+
throw new LuaScriptException("Unknown return type", "");
257298
}
258299
}
259-
catch (LuaScriptException ex)
260-
{
261-
logger?.LogError(ex.InnerException ?? ex, "Error executing Lua script callback");
262-
while (!RespWriteUtils.WriteError("ERR " + (ex.InnerException ?? ex).Message, ref dcurr, dend))
263-
SendAndReset();
264-
return true;
265-
}
266-
catch (Exception ex)
300+
else
267301
{
268-
logger?.LogError(ex, "Error executing Lua script");
269-
while (!RespWriteUtils.WriteError("ERR " + ex.Message, ref dcurr, dend))
302+
while (!RespWriteUtils.WriteDirect(CmdStrings.RESP_ERRNOTFOUND, ref dcurr, dend))
270303
SendAndReset();
271-
return true;
272304
}
273-
return true;
274305
}
275306
}
276307
}

0 commit comments

Comments
 (0)