Асинхронизация запроса к бд

Dertiende

Активный участник
Баллы
61
Всем привет! Прошу помочь с примером реализации getSchelduler.runTaskAsynchronously. Чем проще это будет, тем собственно лучше.
Вопросы:
- Как его вызывать при обработке команды?
- Какие требования к методу и его содержимому?(взаимодействия с BukkitAPI внутри метода не предусмотрено)

Есть метод в плагине, который создает таблицу с чанками для дальнейшего хранения в ней информации по чанкам. Чанков много...
С Java знаком постольку поскольку, поиск по гитхабу и существующим темам задачу не упростил.
Сам метод:
PHP:
public Runnable dbChunksRefresh(World w, int radiusX, int radiusZ)
    {
        try
        {
            String wName = w.getName();

            String url = "jdbc:mysql://localhost:3307/minetest";
            Connection con = DriverManager.getConnection(url,"root","");
            String sqlDrop = "DROP TABLE IF EXISTS "+wName+";";
            String sqlCreate = "CREATE TABLE IF NOT EXISTS "+wName+" (" +
                    "Id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (Id), " +
                    "x INT, " +
                    "z INT, " +
                    "Region INT);";
            Statement Table = con.createStatement();
            Table.executeUpdate(sqlDrop);
            Table.executeUpdate(sqlCreate);

            int xMax = radiusX + 500;
            int zMax = radiusZ + 500;
            int xMin = -xMax;
            int zMin = -zMax;
            log.info("xmin:"+xMin);
            log.info("zmin:"+zMin);
            log.info("xmax:"+xMax);
            log.info("zmax:"+zMax);
            log.info("radiusx:"+radiusX);
            log.info("radiusz:"+radiusZ);

            int startX = findChunkStartPoint(xMin);
            int startZ = findChunkStartPoint(xMin);;
            log.info("startx:"+startX);
            log.info("startz:"+startZ);

            int x = startX;
            int z = startZ;
            log.info("x:"+x);
            log.info("z:"+z);

            while (x<=radiusX)
            {
                log.info("working on: "+x);
                while (z<=radiusZ)
                {
                    String sql = "INSERT INTO "+wName+" (x, z) Values (?, ?);";
                    PreparedStatement insertChunk = con.prepareStatement(sql);
                    insertChunk.setInt(1,x);
                    insertChunk.setInt(2,z);
                    insertChunk.executeUpdate();
                    z+=16;
                }
                x+=16;
                z = startZ;
            }

        }
        catch (Exception e)
        {
            log.warning(e.getMessage());

        }
        return null;
Очень прошу любителей отправлять молодежь на изучение мат.части проявить терпения.
 
Криво, но вроде запускается.
Если раньше он просто через минуту выключался по таймауту, то теперь работает +- 2 минуты, успевает ~500к значений (больше половины) обработать, после чего виснет.
Может ли это быть связанным с бд? (MariaDB)
PHP:
public boolean onCommand(CommandSender sender, Command cmd, String cmdLabel, String[] args)
    {
        if(cmd.getName().equalsIgnoreCase("regen")) {
            ChunkLIstGenerator cnk = new ChunkLIstGenerator();
            List<Map<String, String>> wSizeList = null;
            wSizeList = (List<Map<String, String >>) getConfig().getList("worlds", wSizeList);
            Map<String,List<Integer>> wSizeMap = new HashMap<>();
            for (Map<String,String > i: wSizeList)
            {
                List<Integer> temp = new ArrayList<>();
                temp.add(valueOf(i.get("x")));
                temp.add(valueOf(i.get("z")));
                wSizeMap.put(i.get("wrld"), temp);
            }
            World myWorld = Bukkit.getWorlds().get(0);
            List<String> worlds = cnk.getAllWorldsNames();
            String needOnlyWorld = null;
            try
            {
                needOnlyWorld = args[0];
                log.info("regen "+needOnlyWorld+" only");
            }
            catch (Exception e)
            {
                log.info("No args");
            }
            if (args != null) {
                if (wSizeMap.containsKey(needOnlyWorld))
                {
                    World w = Bukkit.getWorld(needOnlyWorld);
                    String finalNeedOnlyWorld = needOnlyWorld;
                    Bukkit.getScheduler().runTaskAsynchronously(WorldRegen.getPlugin(WorldRegen.class), () -> {
                        cnk.dbChunksRefresh(w,wSizeMap.get(finalNeedOnlyWorld).get(0),wSizeMap.get(finalNeedOnlyWorld).get(1));
                        log.info("updated chunk list");
                    });

                }
            }

PHP:
[00:20:41 INFO]: startx:-10496
[00:20:41 INFO]: startz:-10496
[00:20:41 INFO]: x:-10496
[00:20:41 INFO]: z:-10496
[00:23:34 ERROR]: The server has stopped responding!
[00:24:15 ERROR]: Please report this to http://www.spigotmc.org/
[00:24:18 ERROR]: Be sure to include ALL relevant console errors and Minecraft crash reports
[00:24:32 ERROR]: Spigot version: git-Spigot-1.7.9-R0.2-208-ge0f2e95 (MC: 1.7.10)
[00:24:42 ERROR]: ------------------------------
[00:24:55 ERROR]: Server thread dump (Look for plugins here before reporting to Spigot!):
[00:25:31 ERROR]: ------------------------------
[00:25:39 ERROR]: Current Thread: Server thread
[00:25:49 ERROR]:       PID: 15 | Suspended: false | Native: false | State: RUNNABLE
[00:25:55 INFO]: Dertiende lost connection: Timed out
[00:25:56 ERROR]:       Stack:
[00:25:59 ERROR]:               net.minecraft.server.v1_7_R4.Vec3D.a(SourceFile:8)
[00:26:00 ERROR]:               net.minecraft.server.v1_7_R4.Navigation.j(SourceFile:186)
[00:26:00 ERROR]:               net.minecraft.server.v1_7_R4.Navigation.i(SourceFile:137)
[00:26:05 ERROR]:               net.minecraft.server.v1_7_R4.Navigation.f(SourceFile:127)
[00:26:20 ERROR]:               net.minecraft.server.v1_7_R4.EntityInsentient.bn(EntityInsentient.java:424)
[00:26:32 ERROR]:               net.minecraft.server.v1_7_R4.EntityLiving.e(EntityLiving.java:1549)
[00:26:40 INFO]: AutoSaving
[00:26:41 ERROR]:               net.minecraft.server.v1_7_R4.EntityInsentient.e(EntityInsentient.java:294)
[00:26:53 ERROR]:               net.minecraft.server.v1_7_R4.EntityAgeable.e(EntityAgeable.java:112)
[00:26:56 ERROR]:               net.minecraft.server.v1_7_R4.EntityAnimal.e(SourceFile:37)
[00:27:22 ERROR]:               net.minecraft.server.v1_7_R4.EntityLiving.h(EntityLiving.java:1409)
[00:27:29 ERROR]:               net.minecraft.server.v1_7_R4.EntityInsentient.h(EntityInsentient.java:155)
[00:27:40 ERROR]:               net.minecraft.server.v1_7_R4.World.entityJoinedWorld(World.java:1620)
[00:27:55 ERROR]:               net.minecraft.server.v1_7_R4.World.playerJoinedWorld(World.java:1595)
[00:28:01 ERROR]:               net.minecraft.server.v1_7_R4.World.tickEntities(World.java:1460)
[00:28:05 ERROR]:               net.minecraft.server.v1_7_R4.WorldServer.tickEntities(WorldServer.java:516)
[00:28:10 ERROR]:               net.minecraft.server.v1_7_R4.MinecraftServer.v(MinecraftServer.java:706)
[00:28:27 ERROR]:               net.minecraft.server.v1_7_R4.DedicatedServer.v(DedicatedServer.java:289)
[00:29:54 ERROR]:               Locked on:java.io.PrintStream.flush(Unknown Source)
[00:29:54 ERROR]:               Locked on:sun.nio.cs.StreamEncoder.flush(Unknown Source)
[00:29:54 ERROR]:       Stack:
[00:29:54 ERROR]:               java.io.FileOutputStream.writeBytes(Native Method)
[00:29:54 ERROR]:               java.io.FileOutputStream.write(Unknown Source)
[00:29:54 ERROR]:               java.io.BufferedOutputStream.flushBuffer(Unknown Source)
[00:29:54 ERROR]:               java.io.BufferedOutputStream.flush(Unknown Source)
[00:29:54 ERROR]:               java.io.PrintStream.flush(Unknown Source)
[00:29:54 ERROR]:               java.io.FilterOutputStream.flush(Unknown Source)
[00:29:54 ERROR]:               sun.nio.cs.StreamEncoder.implFlush(Unknown Source)
[00:29:54 ERROR]:               sun.nio.cs.StreamEncoder.flush(Unknown Source)
[00:29:54 ERROR]:               java.io.OutputStreamWriter.flush(Unknown Source)
[00:29:54 ERROR]:               org.bukkit.craftbukkit.libs.jline.console.ConsoleReader.flush(ConsoleReader.java:707)
[00:29:54 ERROR]:               org.bukkit.craftbukkit.v1_7_R4.util.TerminalConsoleWriterThread.run(TerminalConsoleWriterThread.java:42)
[00:29:54 ERROR]:               java.lang.Thread.run(Unknown Source)
>
 
А нафига тебе вообще хранить чанки в бд?
 
Мне показалось, что есть смысл в том, чтобы одноразово задать сетку чанков, и потом туда записывать, на каких чанках создали приват (приваты по чанкам). И для выполнения регенерации выгружать только пустые чанки и регенить.
 
Мне показалось, что есть смысл в том, чтобы одноразово задать сетку чанков, и потом туда записывать, на каких чанках создали приват (приваты по чанкам). И для выполнения регенерации выгружать только пустые чанки и регенить.
Не, проще будет записывать во время создания региона, а для регенерации - WE в помощь.
 
Регенерация это очень медленный процесс. Лучше с ним не баловаться.
 
Воткни 4тб диск, долго не засрут твою карту.
По моему это не совсем круто, делать мусорку ещё больше вместо того, чтобы чистить её.
Мир, который планируется чистить меньше 10к блоков радиусом.
Можете рассказать, в чем именно заключается проблема при длительной регенерации? У ядра проблемы со стабильностью?
 
По моему это не совсем круто, делать мусорку ещё больше вместо того, чтобы чистить её.
Мир, который планируется чистить меньше 10к блоков радиусом.
Можете рассказать, в чем именно заключается проблема при длительной регенерации? У ядра проблемы со стабильностью?
Проблема в тебе. Ты фризишь сервер, вот он и ребутится.
 
Для асинхронной работы с миром можно использовать API AsyncWorldEdit/FastAsyncWorldEdit
 
Назад
Верх