4

I use Tarantool with vshard module. When bucket_id is set, the data is distributed across the cluster. Each node has its own set of bucket_ids. How to make a space so that it is fully accessible on every node (dictionary)?

1 Answers1

2

I use the following snippet to run a function on all storages (may be there's a better way).

Suppose we have a function on storages:

local function putMyData(rows)
    box.atomic(function()
        for _, row in ipairs(rows)
            box.mySpace:put(row)
        end
    end)
end

box.schema.func.create("putMyData", { if_not_exists = true })
box.schema.role.grant("public", "execute", "function", "putMyData", { if_not_exists = true })
rawset(_G, "putMyData", putMyData)

Then the following helper may be used to call the function:

local function callAll(mode, fnName, args, resHandler, timeoutSec)
    local replicaSets, err = vshard.router.routeall()
    if err ~= nil then
        error(err)
    end

    local count = 0
    for _, _ in pairs(replicaSets) do
        count = count + 1
    end

    local channel = fiber.channel(count)

    local method
    if mode == "read" then
        method = "callbro"
    else
        method = "callrw"
    end

    for _, replicaSet in pairs(replicaSets) do
        fiber.create(
            function()
                local res, fErr = replicaSet[method](replicaSet,
                    fnName, args, { timeout = timeoutSec or opts.timeout })
                channel:put({ res = res, err = fErr })
            end)
    end

    local results = { }

    for i = 1, count do
        local val = channel:get()
        if val.err ~= nil then
            error(val.err)
        end

        if resHandler == nil then
            results[i] = val.res
        else
            resHandler(val.res, results)
        end
    end

    return results
end

Mike Siomkin
  • 667
  • 8
  • 15