Testing with ease: master-master replication in Tarantool



As an example of the master-wizard of a Tarantool cluster, I propose to make a small text multiplayer game where each participant seeks to score more points.



, . . , Tarantool .



, - ? , , «», , «», , , . . , . .



ascii-, , .



, , , , .








- bomberman. 80x40. . , . . , .








  1. Tarantool 2- https://bit.ly/2IL3JSc



  2. :





$ git clone https://github.com/filonenko-mikhail/mmgame.git
$ cd mmgame


  1. :

    • , .

      $ reset && clear
      $ tarantool ./foodmaker.lua 127.0.0.1:3301
  2. :

    • — ;
    • — , ;
    • — .

      $ reset && clear
      $ tarantool ./player.lua 127.0.0.1:3301 127.0.0.1:3302 ./player1data
  3. . :

    • , ;
    • .
  4. 2 :


$ reset
$ tarantool ./player.lua 127.0.0.1:3301 127.0.0.1:3303 ./player2data


  1. — .


Troubleshooting



- , .

, , , , .



  • ,

    • reset <Enter>
  • ER_REPLICASET_UUID_MISMATCH: Replica set UUID mismatch: expected 4f8d5028-3f4e-4f8f-a237-bb3db620813f, got 03982784-c023-4661-afe1-96752d90df86

    • , ,
  • ER_UNKNOWN_REPLICA: Replica 904c70b2-be5a-4e5f-afd0-daa0be66f729 is not registered with replica set d4f37bc6-3a71-43a2-8ca5-65e2bcc0bfda

    • ,


, - , https://bit.ly/37l0awn













«»



(), .



:



ID Icon X Y Type Health
uuid symbol int int string int


ID. .



Icon .



X, Y .



Type :



  • ;
  • ;
  • ;
  • ;
  • ;
  • .


Health :



  • ;
  • .


.





:



  • , : {ID};
  • : {x, y, type};
  • : {type};
  • : {health}.







, . .



, , .



, , , . uuid.



, . X, — Y. Y , — X, . «». , . , , .



:



  • , .
  • , .


, , , .








-, , . 32, Tarantool. , , , .



Tarantool — , . instance uuid. replicaset uuid.



, .



, , . , .



:



  • foodmaker () cluster uuid.




  • , . .




  • .




  • «».




full-mesh , . , , .





Tarantool



Tarantool, , , — .



Tarantool Lua JIT-.



Lua.



Lua-. , – Tarantool Cartridge.







box.cfg. .



:



  • replication
  • replication_connect_quorum
  • replication_connect_timeout


, , , . , :



box.cfg{
    listen=server,
    replication_connect_quorum=0,
    replication_connect_timeout=0.1,
    work_dir=wrkdir,
    log="file:foodmaker.log",
}







, , .



box.cfg{
    listen=localserver,
    replication={ remoteserver },
    replication_connect_timeout=60,
    replication_connect_quorum=1,
    work_dir=wrkdir,
    log="file:player.log"
}




, , , , , , , .



:



  • add_player.



  • .



  • , .



  • :



    function add_player(server)
    if box.session.peer() == nil then
        return false
    end
    local server = uri.parse(server)
    local replica = uri.parse(box.session.peer())
    replica.service = server.service
    replica.login = conf.user
    replica.password = conf.password
    replica = uri.format(replica, {include_password=true})
    local replication = box.cfg.replication or {}
    local found = false
    for _, it in ipairs(replication) do
        if it == replica then
            found = true
            break
        end
    end
    if not found then
        table.insert(replication, replica)
        box.cfg({replication={}})
        box.cfg({replication=replication})
    end
    return true
    end


  • , .



    _G.conn = netbox.connect(remoteserver,
    {wait_connected=false, reconnect_after=2})
    conn:on_connect(function(client)
    fiber.new(function ()
        local rc, res = pcall(client.call, client, 'add_player', {localserver})
        if not rc then
            log.info(res)
        end
    end)
    end)









. , .



. , if_not_exists=true. DDL-, , .



Data Definition Language



DDL-, :



  • .

    box.schema.space.create(<name>, options)
  • .

    box.space.<name>:format(
    {{name=<field_name>, type=<field_type>},
     ...,
    })
  • .

    box.space.<name>:create_index(<index_name>,
    {
        parts={{field=<field_name> type=<field_type>},
            ...,
        },
        unique=false|true,
    })
  • .

    box.schema.user.create(<name>, {password=<pass>})
  • .

    box.schema.user.grant(<name>, ....)
  • .

    box.schema.func.create(<name>)







. , .



while true do
    if type(box.cfg) ~= 'function'
    and box.space[conf.space_name] ~= nil 
    and not box.info.ro then
        break
    end
    fiber.sleep(0.1)
end





Tarantool



Tarantool .



, :



  • lua, .
  • .


— , , , . — , :)



, , :



  • .

    box.ctl.on_schema_init(<CALLBACK>)
  • .

    box.ctl_on_schema_init(function()
    box.space._space:on_replace(<CALLBACK 2>)
    end)
  • .

    box.ctl.on_schema_init(function()
    box.space._space:on_replace(function(old, space)
        if not old and sp and sp.name == <USER SPACE NAME> then
            box.on_commit(<CALLBACK 3>)
        end
    end)
    end)
  • , , ^W^W — , .

    box.ctl.on_schema_init(function()
    box.space._space:on_replace(function(old, sp)
        if not old and sp and sp.name == <USER SPACE NAME> then
            box.on_commit(function()
                box.space[sp.name]:on_replace(<USER TRIGGER>)
            end)
        end
    end)
    end)







, — .



, .



— (, , , ). . , . , fiber.sleep(N) fiber.yield(), io-.



.



Data Modification Language





-- 
box.space.Name.insert({id, sprite, x, y, type, health})
--    
box.space.Name.put({id, sprite, x, y, type, health})




box.space.Name.update({primary key}, {{operation, field, value}})




box.space.Name.delete({primary key})







. ID instance uuid.



.



, tcgetattr tcsetattr LuaJIT FFI.



.



box.begin()

local rc, res, err = pcall(function()
    ... 
    box.space[conf.space_name]:put(bomb)
    box.space[conf.space_name]:update(player['id'], 
        {{'-', conf.health_field, conf.bomb_energy}})
end)
if not rc then
    log.info(res)
    box.rollback()
else
    box.commit()
end


.








. , . .








N .



.








, , , . .








: «» «».



«» , . , , ..



«» «» .



«» , , , , .








, .



  • .
  • 0 .


.








, , .








, — . .



replication_anon.



box.cfg{listen=localserver,
        replication={ remoteserver },
        replication_connect_timeout=60,
        replication_connect_quorum=1,
        read_only=true,
        replication_anon=true,
        work_dir=wrkdir}









:



  • , «-» Tarantool.
  • .
  • , .
  • , .


Tarantool, codesign .



:



  1. Tarantool .
  2. Telegram-.



All Articles