How to properly load a Lua script in StackExchange.Redis? - lua

In the StackExchange.Redis docs for scripting, it says a LoadedLuaScript can be used to avoid retransmitting the Lua script to redis each time it is evaluated. It then gives an example where the script is loaded into the server. I assume this shouldn't be done everytime you call the script, so where should the scripts be loaded?
Scripts are not persitent if redis server is restarted, so how should this be handled? Should they be loaded in ConnectionRestored event of the ConnectionMultiplexer? Presumably you would need to store them in a ConcurrentDictionary?

StackExchange.Redis handles Lua script caching internally. Normally you don't have to care about loading Lua scripts manually to redis.
StackExchange.Redis automatically transmits the Lua script to redis on the first call to 'ScriptEvaluate'. For further calls of the same script only the hash is used:
var prepared = LuaScript.Prepare(script);
prepared.Evaluate(someDb); // loads the script to redis and calls it
var prepared2 = LuaScript.Prepare(script);
prepared2.Evaluate(someDb); // calls the script by it's hash
LoadedLuaScript might be useful for edge cases like loading without executing.
I also clarified the official doku.
Background information
The library tries to call the script by it's hash and if the script is missing it gets a NOSCRIPT error and then transmits the script.
See ScriptEvalMessage:GetMessages in https://github.com/StackExchange/StackExchange.Redis/blob/main/src/StackExchange.Redis/RedisDatabase.cs
The behavior is also discussed and explained in the official StackExchange.Redis github repo:
https://github.com/StackExchange/StackExchange.Redis/issues/1246
https://github.com/StackExchange/StackExchange.Redis/issues/1371

Related

Cross site issue with Microsoft Graph Toolkit

I'm following this tutorial to create a simple web app with a Microsoft 365 login. I'm currently getting this error when debugging locally (http://localhost:8080):
Warning:
mgt-loader.js:61 A parser-blocking, cross site (i.e. different eTLD+1) script, https://unpkg.com/#microsoft/mgt/dist/bundle/wc/webcomponents-loader.js, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If blocked in this page load, it will be confirmed in a subsequent console message. See https://www.chromestatus.com/feature/5718547946799104 for more details.
In Azure, I have the Redirect URIs set up to match (http://localhost:8080).
After some googling, I tried adding async, but then I get this warning and the login button doesn't appear:
mgt-loader.js:61 Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
What would be causing this warning and how can I fix it?
First, check out how document.write works: https://developer.mozilla.org/en-US/docs/Web/API/Document/write
You will understand why you cannot run document.write in asynchronous context (try running document.write('Hello world!'); in console on any page).
Warning tells you that a parser blocking (synchronous), cross site (not coming from the same domain as website) scripts can be blocked by Chrome in the future if someone has unstable or bad internet connection.
If you want it to run synchronously without that warning, you have to bundle that JS code with your own, or just serve it from your own origin, same as your website (e.g. localhost:8080). You can download #microsoft/mgt npm package and for bundling - use gulp, webpack or other tool of your choice.
https://unpkg.com/#microsoft/mgt#2.4.0/dist/bundle/wc/webcomponents-loader.js
This script tries to differentiate between async and sync contexts (line 175) and run document.appendChild (instead of write) for async context - but for some reason the check fails (readyState === loading).
https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
How to check if an Javascript script has been loaded Asynchronously (Async) or async attribute is present?
If you want to run this in non-blocking manner, you could try to fix the script by yourself.
There is a Github repo for that toolkit (https://www.npmjs.com/package/#microsoft/mgt), but there is no issue regarding async loading, nor regarding the warning that you have noticed - so maybe nobody else has noticed or thought about it yet.

How can I load a lua library in rc.lua for later use by awesome-client?

For background, I'm currently using notify-send to produce dbus notifications when a long script finishes but I'd like to make better notifications with naughty.
I found this simple script https://gist.github.com/lgaggini/51a35f363b7f1966971e869f3fbb5335 for sending naughty notifications using awesome-client. It initializes the naughty library every time it runs, which seems messy since it only needs to be loaded once per session.
In my rc.lua, I tried changing the line
local naughty=require("naughty")
remove local: still needed to require naughty through a lua prompt or awesome-client after restarting awesome
add global: that's not actually a keyword in lua so it breaks my config
Is there something I can do here or elsewhere in my rc.lua that will make this (or any other) library available to awesome-client without an extra step?

execute lua string as lua code

I want to share lua modules with coworkers. In order to get the latest version of shared modules I want to store and fetch them with a web server.
My questions is:
Is it possible to load lua code directly from http request or string?
I want to achieve something like that :
module = [[
local sharedModule = {}
function sharedModule.greet(name) print("hello " .. name) end
return sharedModule
]]
greeter = require (module)
greeter.greet("john")
Maybe this is not the right thing to do. Is there a better approach than this one?
There's a whole section in Programming in Lua devoted to that. Your needs will be directly fulfilled with loadstring in Lua 5.1 and older, or load in Lua 5.2 and newer.
I would carefully verify the code you're actually executing, though. At the very least, version it (running a wrong version would most probably end up in all sorts of problems, if the code being run depends on the environment being in a certain state). Optimally checksum and sign the code, and verify the signature before doing anything. If your environment isn't protected, this is essentially a huge backdoor opening.
You could also use rings library to isolate the code you're running within the Lua environment itself. It might not be airtight security-wise, but should at least prevent the received code from crashing your application if/when it goes awry.

local autocomplete using jQuery-Autocomplete and mockjax

https://github.com/devbridge/jQuery-Autocomplete
found this tutorial and was able to run it implement it on my app.my problem is, it wont run on local computer/app i think the problem is with mockjax is there way to make this tutorial run locally?or is there other way to make an autocomplete locally?this example is about autocomplete.
In the config lookup is for local data that doesn't rely on external requests. This would rely on loading in the data through JS on the client.
If you want to run it locally why not boot up a simple http server with python and make a get request to a local file?
See here line 133: https://github.com/michaelBenin/Airport-Distance-Calculator/blob/master/script.js

Ruby on Rails: Executing JAR

Folks, i'm trying to execute a jar file inside RoR. Thanks to SO, I figured using IO::popen calls to execute a jar file.
Requirements:
- To login to site: To let our company employees login. Its a Java library which does some magic and figures if the username/password is valid. Which I did using,
result = IO::popen("java -cp auth.jar com.name.auth.LDAPLookup " + params[:username] + " " + params[:password]).read
p result
output: ["Authorized", "email", "id"]
No input sanitizing done. This is risky. Anyone could type something up in username/password and that will be executed in the server.
I'm not sure how to do this. One option I want to try is to use fork() or Process APIs to launch "java" and pass arguments. Couldn't figure out however. Any other thoughts?
Aside from the issue you mention, this sounds pretty painful in terms of performance (you're waiting around for the JVM to start up on every request, after all).
Two solutions jump out at me:
Look what the library does, and see if you really need to call out to Java for this; in particular, if it's just a question of making a lookup in an LDAP directory with a set of canned parameters, there are plenty of gems for that
If you must make use of Java classes from Ruby, strongly consider using JRuby, which will let you call the Java class in question directly, with neither the overhead of restarting the JVM on each call, nor the risk which comes with trying to correctly escape your arguments from Ruby to the shell to the JVM, and back.

Resources