Run function as var/value from DB

Hi,
I’m new to Golang so sorry if I say or write something completely off :slightly_smiling_face:

I’m trying to run functions as jobs and I store function names in DB and then try to run them as Cronjob, and it works till point where it needs to execute.

So I tried to map them:

var funcs = map[string]func() {"countRegistrations":countRegistrations}

and then execute it with:

funcs["\""+name+"\""]()

Where name is retrieved from DB
but this throws memory error panic.

I also figured that this is not flexible since I can add new job (func name in DB) but for the mapping I have to restart DB.

Is there a way to call the function which name is stored in the variable name?

Thanks

Hello there. Are you sure you need those extra quotes in key? It’s always better to always check existence, something like

fn, ok := funcs[name]
if ok {
    fn()
}

Plus, you can probably add some job to update funcs mapping to reload the map with new values from db.

Hey, thanks for tips, I think i tried without quotes and it was nil, but it might be possible that it was nil cause of db fetching problems i had previous, I’ll try.

As for the job to update map, indeed a good option, i already have it that is fetching them from db, forgot that i can update map also :wink:

Thanks a lot

Indeed it works now without quotes :slight_smile: nice.

but i’m not sure how to append it to the map, this is how it looks now:

var funcs = map[string]func() {"funcA":funcA}

so i’m noty sure how to call append cause of these quotes again :slight_smile:

Are you trying to append golang object (function) into the map or is it already in db and you just use the name to call the object?

Map append works something like this:

m := make(map[string], 0)
m[key] = func

The idea was to have a job picking up new records from DB, that don’t have jobId updated, so funName field was just string (varchar) name of the function I want to run from that main job (as another job and then have that function run as separate job). So it would allow me to add more jobs dynamically.

I first tried to invoke funName just like that but got:
./main.go:137:4: funName (variable of type string) is not used
so that lead me to that funcs map that have literal string mapped to func name, it works now when I have hardcoded string and name in that map :slight_smile:

I think you would need to use reflection to call your func via its name

See Go Playground - The Go Programming Language

Let me look it up the , thanks

Is there a way to parametrise "hello" also, do that i don’t have to hardcode key in the code, and then no need to restart mail every time i add new record?

I’m not sure I understand what you’re asking. Are you saying you want to pass a param to your function? I modified the example Edward posted for you here:

Sorry for being confusing;)

The goal was to have a string = name of the function that need to be run/executed as a job.

So for example on your code snippet, key on line 13 to be dynamically added from db.
So i have a job (cronjob) in main.go that fetches all pending jobs and than, if one of the records doesn’t have job.ID() updated in db i want to run it, and name field is the function name that will have to be executed.

So as the first reply, i managed to run it by having a map{string name: function name}, so was wondering if i can push new keys: func names to that map, but I read that it is not so safe to do it like that cause then it is exposing code injection.

You will need to modify + deploy the code to modify the map.

1 Like

Exactly. Or you could shell out to a scripting language to execute arbitrary stuff. for example, if you wanted to execute arbitary JavaScript there are several approaches to do that:

If you went that route, you could just store a chunk of JavaScript in your database instead of function name. Etc.

Bad code

var funcs = map[string]func() {"countRegistrations":countRegistrations}

funcs["\""+name+"\""]()

Good code

var funcs = map[string]func() {"countRegistrations":countRegistrations}

yourFuncName := "countRegistrations"

fn, ok := funcs[yourFuncName]
if !ok {
    panic(fmt.Errorf("func not found: %s", yourFuncName)
}
fn()

Thanks all for the help, i leaft it as a map