In this video, use the StackExchange.Redis library to load and execute— eval or evaluate—Lua scripts on a Redis server.
- [Instructor] Let's take a look at Lua scripts from within a C# client. I'll drag and drop to copy the last file. Hold down Control. This will be 10_02. Rename the class. And delete all the tests.
OK, so we're going to use the Redis object to actually talk to the Redis server and give it a Lua script as a string to execute. So the way to start, the simplest way, it to just have a string that is your script. And I'll use the example from before. So local variable name equal to the text anton, and we'll just return name. So then... Create the variable LS for Lua script, which will be LuaScript as in the Lua script class from the StackExchange name space.
Dot prepare. myLuaScript redis.Script Evaluate that prepared script. Now we'll come back to the variations on the evaluate, but the fact is here we have a piece of text that is understood by Lua that will be run inside of Redis. So let's just start there. Build. Go to our test window.
02 run. And OK, so we've done the round trip to the server, given the piece of text, essentially run eval with this text, zero keys, zero arguments. OK, let's do something a little bit more... Practical. Copy and paste this method. Rename it. Make this Lua2. And so now our script will be text and we'll keep the text without even this prepare, we'll come back to this later. And we'll evaluate the script, but this time we'll use some of the additional arguments available to us.
And so what you'll see is one of the overloads say we can give it a piece of text. The third one, fourth one and disguise. So in the forth overload we can see it can take text just a string parameter, and then we can explicitly specify the keys and the values for the script. So remember it was in the eval command definition. Eval, the text, the number of keys, the keys and then the arguments. So we can do a new Redis key array.
It'll be an empty one. A new Redis value array. It will start out empty as well. And so this is the way we wound run these scripts most of the time. Copy and paste the string variable there. And so this is the closest we typically get to the eval command. So now if I want to replace this hard-coded string here, delete the text, delete the quotes. ARGV for arguments as a vector. One based index. And so if I place one argument in here, this argument is argument number one, and will be available within the script.
And so when I run that script in that way, let's check that the result... toString in this case... Is equal to the text we provided. So that should be fairly obvious, but the thing to notice is that the list of keys is provided, and the list of values are provided. So we have those two arguments exactly as the eval command typically uses them. So build all. Let's run Lua2. Right-click, run, and success.
And so as you build out your commands, you'll find that you use keys, arguments and so forth within the Lua script. Let's do one more. Copy and paste the method. This is number three. Let's do something a little bit more elaborate as far as the script is concerned, and manage its formatting. So I'll use the at symbol to allow us to have new line characters within the script. And now this is a matter of taste how you want to format it.
And so let's talk to Redis. So we can say Redis.call, and actually make a Redis... Command. Run. In this case we'll say set. And we would like to use one of the keys we are about to provide, and one of the arguments we're about to provide to run the set command. And so what we're literally doing is while the Lua script is being evaluated, we'll call into Redis and say set a given key to a given value. Copy and paste.
Let's do this twice. Two... And two. And so now we know that two arguments provided to the Lua script is going to be used to set two keys in Redis, and the keys themselves will also provide it to the Lua script, and then we can use them. So for example... Local variable FirstName can be set to argument one, or... Instead of going for the arguments directly, I can say Redis dot call, and let's get a value directly from Redis.
And in this case, based on keys one. So now basically we are saying we would like to assign a value to a local variable in Lua based on a value we are retrieving, fecthing, from Redis itself. So FirstName, LastName. So now this will be key number two for which we want the value. And then we can return my string catenation. This is Lua specific, I'll say FirstName, dot, dot, an additional string, which is just a space, and then dot, dot, and another variable.
OK. So now if we run this script by just saying SciptEvaluate, we are going to run the script as per the text, but we should provide the two keys. So I'm just using shorthand here, key first name and key last name. And then in the values also, the first name and the last name. So the only thing we're not doing explicitly from the client side here... The library will determine the number of keys and provide that to the eval command. We don't have to manage that explicitly.
And so now when we run that script, the result ought to be that. Build. Run script number three. And we're off to the races. Success. And so now as you build up your scripts in a more elaborate code, you're going to have if statements and loops and some error handling, perhaps, and other structures to them. And so we would have an elaborate list of keys, an elaborate list of arguments, and we would have to pass those in as the two arrays, and then the Lua script as text.
OK, let's copy and paste this method one more time. So Lua variation number four. And so this time we're not going to execute the text as a string being passed to the eval command. We are going to put it through some processing first. So as we have the setup here, we are using arguments and keys, and so forth, but what we can do is write a simpler version of the script that is in fact going to be used by the ScriptEvaluate method after we've prepared the script.
So watch this. We have... Our Lua script as a LuaScript dot prepared script. So myLuaScript text is going to go in there as an argument, and what comes out is something that was already processed, preparsed by the StackExchange client. And so then... Leaving out the Redis calls for a moment... I can use the old notation that you might be familiar with from .NET.
So when we say parametrized queries... We use the at symbol to say that there will be a parameter provided, and it will be data that needs to be added to this piece of text. And so the Lua script can then look a lot cleaner if we use parametrized queries like in this way, and it's just something the StackExchange client is doing for us to make things look really good. So we can write simpler, cleaner Lua scripts in this way, prepare them, but then we don't pass the text, we provide the prepared script, and then the values are not provided in a RedisValue array.
You can actually take any object that you have as long as it has properties that match the names of the variables. So I'll create a new anonymous object with a FirstName, and the LastName property. And so now we have a prepared Lua script, and we have... Any object that you've got but has the appropriate properties to match FirstName as a parameter, FirstName as a property.
LastName field or property, LastName as a parameter. Save all, build. Run Lua script four. Run selected tests. And success. And so now you can write really cleen, well-simplified Lua scripts, and provide essentially objects with the fields that you need as a parameter to the ScriptEvaluate method, and it will do the mapping from the properties into the parameters.
So for those cases where you do need to write scripts to be run on the server for the benefit of the isolation, it's only going to be your script running on that server at that time. And for the case where you like a stored procedure approach to writing scripts, do use the StackExchange, LuaScript and LoadedLuaScript prepare methods, and do remember that your scripts can be cached, and so it's well worth placing them in external files instead of having them as strings in your code. Load them from the files, treat them like stored procedures, and know that Redis will actually cache them for you.
- What is Redis?
- Installing Redis on a Windows machine
- Deploying the latest version of Redis into a container
- Connecting with C# clients
- Working with data types in Redis
- Key expiration and expiration policies
- Working with lists, sets, and hashes in Redis
- Working with batches and transactions
- Using Redis with ASP.NET web apps