How to run an Erlang MapReduce function on Riak? - erlang

I'm new to Riak and new to Erlang. I have successfully created and run JS MapReduce jobs, now I'm trying to execute the following Reduce function:
http://web.archive.org/web/20130329021000/http://contrib.basho.com/delete_keys.html
What are the steps to execute this reduce function? Specifically,
Where should I put the code?
What should I type into addReducePhase( ) ?
Thanks

You should write something like:
MapReduceResult result = client.mapReduce("myBucket")
.addLinkPhase("bucketX", "test", false)
.addMapPhase(new NamedJSFunction("Riak.mapValuesJson"), false)
.addReducePhase(new NamedErlangFunction("riak_kv_mapreduce", "reduce_sort"), true)
.execute();
In this case the reduce phase call the function reduce_sort of erlang module riak_kv_mapreduce.
In your case you should call
.addReducePhase(new NamedErlangFunction("reduce_functions", "delete"), true)
(the true at the end is a flag that set if results have to be returned to client - last step - or not -intermediate step -)
The Erlang files should be compiled as .beam before use and added to 'add_paths' parameters in riak.config like
{add_paths, ["/home/vinz/riak/custom_modules/"]}
where /home/vinz/riak/custom_modules is the directory containing the compiled Erlang modules.
Refer to Basho Java Client readme for further information.
I hope this helps!

Related

luaL_loadbufferx returns syntaxerrors

I'm working on a personal project and I'm trying to get Lua to work on my embedded device.
I have my own simple file system that works with the the flash drive, and now I'm trying to use modules for the lua scripts that I run on the device.
I have edited linit.c, to make it also load the modules that are existing in the flash drive, and it works for a few modules, but for most of them it just gives me a syntax error when it parses the contents of the module. I have a lua interpreter running on my Windows machine and the code I'm writing is syntactically correct and works, and the Lua API that I use is of the same version 5.4 on the device.
These are the arguments I pass to
luaL_loadbufferx(L, luaCFunction, sizeOfModule, moduleName, "t")
where, L is the lua state, luaCFunction is the lua module wrapped in a C-style return statement, sizeOfModule, moduleName and t is selfexplanatory.
Right now luaL_loadbufferx is called in a loop for every module in my flash-drive, I have overwritten the openf function from the Lua API for these external modules.
This below is one of the examples of a module that gives me
"Syntax Error: PANIC, unprotected error in call to Lua API
[string "module"]:3: '(' expected near 'writeobj'"
File: module.lua
Contents:
function writeobj()
print('Hello World')
end
File: run.lua
Contents:
require ('module')
writeobj()
Does anyone know why this happens or did I not provide sufficient information? Please let me know.
The problem was that I thought the modules passed to the buffer had to be of the LuaToC form, i.e. "return { ...luamodule...}", but changing it to pass the module only to loadbuffer was sufficient enough because it covers the case of it not being in a C style return format.

Can Erlang source code be embedded in Elixir code? If so, how?

Elixir source may be injected using Code.eval_string/3. I don't see mention of running raw Erlang code in the docs:
https://hexdocs.pm/elixir/Code.html#eval_string/3
I am coming from a Scala world in which Java objects are callable using Scala syntax, and Scala is compiled into Java and visible by intercepting the compiler output (directly generated with scalac).
I get the sense that Elixir does not provide such interoperating features, nor allow injection of custom Erlang into the runtime. Is this the case?
You can use the erlang standard library modules from Elixir, as described here or here.
For example:
def random_integer(upper) do
:rand.uniform(upper) # rand is an erlang library
end
You can also add erlang packages to your mix.exs dependencies and use them in your project, as long as these packages are published on hex or on github.
You can also use erlang and elixir code together in a project as described here.
So yeah, it's perfectly possible to call erlang code from elixir.
Vice-versa is also possible, see here for more information:
Elixir compiles into BEAM byte code (via Erlang Abstract Format). This
means that Elixir code can be called from Erlang and vice versa,
without the need to write any bindings.
Expanding what #zwippie have written:
All remote function calls (by that I mean calling function with explicitly set module/alias) are in form of:
<atom with module name>.<function name>(<arguments>)
# Technically it is the same as:
# apply(module, function_name_as_atom, [arguments])
And all "upper case module names" in Elixir are just atoms:
is_atom(Foo) == true
Foo == :"Elixir.Foo" # => true
So from Elixir viewpoint there is no difference between calling Erlang functions and Elixir functions. It is just different atom passed as the receiving module.
So you can easily call Erlang modules from Elixir. That mean that without much of the hassle you should be able to compile Erlang AST from within Elixir as well:
"rand:uniform(100)"
|> :merl.quote()
|> :erl_eval.expr(#{})
No need for any mental translation.
Additionally you can without any problems mix Erlang and Elixir code in single Mix project. With tree structure like:
.
|`- mix.exs
|`- src
| `- example.erl
`- lib
`- example.ex
Where example.erl is:
-module(example).
-export([hello/0]).
hello() -> <<"World">>.
And example.ex:
defmodule Example do
def print_hello, do: IO.puts(:example.hello())
end
You can compile project and run it with
mix run -e "Example.print_hello()"
And see that Erlang module was successfully compiled and executed from within Elixir code in the same project without problems.
One more thing to watch for when calling erlang code from elixir. erlang uses charlists for strings. When you call a erlang function that takes a string, convert the string to a charlist and convert returned string to a string.
Examples:
iex(17)> :string.to_upper "test"
** (FunctionClauseError) no function clause matching in :string.to_upper/1
The following arguments were given to :string.to_upper/1:
# 1
"test"
(stdlib 3.15.1) string.erl:2231: :string.to_upper/1
iex(17)> "test" |> String.to_charlist() |> :string.to_upper
'TEST'
iex(18)> "test" |> String.to_charlist() |> :string.to_upper |> to_string
"TEST"
iex(19)>

Does a BEAM file remember whether it was built with -Werror?

I am working on a tool that deals with BEAM files, and we want to be able to assume the code was compiled with -Werror, so we don't have to repeat validations that are already done by the erl_lint compiler pass.
Is there a way to figure out if the BEAM was built with -Werror?
I'd expect beam_lib:chunks/2 to help here, but unfortunately it doesn't seem to have what I'm looking for:
beam_lib:chunks("sample.beam", [debug_info, attributes, compile_info]).
% the stuff returned says nothing about -Werror, even if I compile with -Werror
It seems that this information would be always stripped
However, if you are in control of compilation process - you can put additional info into beam files, - which will be accessible through M:module_info(compile) and via beam chunks as well.
For example in rebar:
{erl_opts, [debug_info, {compile_info, [{my_key, my_value}]}]}.
And then:
1> my_module:module_info(compile).
[{version,"7.6.6"},
{options,[debug_info, ...
{my_key,my_value}]
The same is true for "discoverability" of this key directly from beam chunks:
2> beam_lib:chunks("my_beam.beam", [compile_info]).
{ok, ... {my_key,my_value}]}]}}
Meaning, that you can "stamp" your beam files with some meta-information easily. So, a workaround may be to stamp those beam files with this mark.

Call a function on terminating/exiting a lua script (an atexit()/cleaning function)

Question: Is there a way to call a function when the lua script is terminated by either the system or a program which has started the script (e.g. a C program)? An atexit()/cleaning function for lua.
The situation: a external C program (call it PROG) manages a lua script (call it SCRIPT) and calls its functions, the lua script uses a separated library (.so, cal it LIB) which reserves resources which should be freed when the lua script exits. The lua script is managed (and thus terminated) by PROG which i can not alter. SCRIPT should notify LIB when it is terminated.
How can this be done?
Note: i'm fairly new to lua so please also explain your answer, much appreciated :)
I'm on Linux using Lua 5.3.1
Currently this seem to work:
a = {__gc = function() print'exit function from LIB called' end}
setmetatable(a,a)
Check out http://lua-users.org/lists/lua-l/2001-08/msg00265.html
You may need to run lua_runprotected call to prevent a stack under flow problem.

How do I modify the code search path for a remote Erlang node?

I'm connected to an Erlang node with -remsh. How do I modify the code path, in order to load a library that wasn't packaged into my release?
All necessary functions to manipulate code loading, path... are in the code module (see doc at erlang otp code module).
You could add the system paths to the list by doing the following:
[code:add_pathz(P) || P <- filelib:wildcard("/usr/lib/erlang/lib/*/ebin")].
After compiling some test code and connecting to a running node I was able to make it work with this:
(app#127.0.0.1)1> code:add_pathz("/path/to/my/compiled/beam").
(app#127.0.0.1)2> tester:hi().
hi!
ok
(app#127.0.0.1)3>

Resources