Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[内置 kit] 轻量的定时入库辅助功能 #303

Open
iohao opened this issue May 30, 2024 · 2 comments
Open

[内置 kit] 轻量的定时入库辅助功能 #303

iohao opened this issue May 30, 2024 · 2 comments
Assignees
Labels
enhancement;功能增强 Function enhancement;功能增强 May support;打算支持,但不紧急 Maybe, but not necessarily;后续版本计划提供的功能 Support extension;可扩展 Support extension;可扩展

Comments

@iohao
Copy link
Owner

iohao commented May 30, 2024

新增功能的使用场景

在游戏开发中,通常会有定时入库相关需求,其目的是

  1. 为了避免阻塞业务线程,而将入库的操作统一放到其他线程中执行。
  2. 减少 DB 操作(因频繁更新而触发的)。

而定时入库则能很好的解决上述两个点。


现在,框架计划加入定时入库的辅助功能。让我们先看下面这个示例

  • 示例中,我们演示了 Hero、Student 延时入库的操作。
  • 同时,我们还演示了同一条数据多次更新的场景

如下所示,当我们把需要更新的数据放到 FlushData 中时,并不会立即更新,而是会在未来的某个时间点执行更新操作(根据开发者的定时策略)。

FlushData flushData = ...
  
@Test
public void test() {
    // 添加需要更新的数据 hero、student
    var hero = new Hero();
    hero.id = System.currentTimeMillis();
    flushData.put(hero.id, () -> {
        heroRepository.update(hero);
    });

    var student = new Student();
    student.id = "student-1";
    flushData.put(student.id, () -> {
        studentRepository.update(student);
    });

    // 下面只会更新最后一条数据。因为 id 相同,后者覆盖前者
    var hero2 = new Hero();
    hero2.id = System.currentTimeMillis();

    flushData.put(hero2.id, () -> {
        hero2.name = "first hero2";
        heroRepository.update(hero2);
    });

    flushData.put(hero2.id, () -> {
        hero2.name = "last hero2";
        heroRepository.update(hero2);
    });
}

@Before
public void setUp() {
    BarSkeletonBuilder builder = ...
    // 在游戏逻辑服启动时,我们只需在业务框架中配置相关更新定时策略。
    builder.addRunner(skeleton -> {
        flushData = FlushData.of();
        // 配置 N 分钟同步一次 DB
        TaskKit.runInterval(new FlushIntervalTaskListener(flushData), 5, TimeUnit.MINUTES);
    });
}

FlushData 是框架提供的一个接口,用于管理需要更新的任务

public interface FlushData {
    ... ...省略部分代码
    /**
     * 添加任务监听回调
     *
     * @param id           id
     * @param taskListener 任务监听回调
     */
    void put(long id, TaskListener taskListener);

    /**
     * 添加任务监听回调
     *
     * @param id           id
     * @param taskListener 任务监听回调
     */
    void put(String id, TaskListener taskListener);
}

其他示例代码

class Student {
    String id;
}

class Hero {
    long id;
    String name;
}

interface HeroRepository {
    void update(Hero hero);
}

interface StudentRepository {
    void update(Student student);
}

小结

使用框架提供的定时入库的辅助功能是简单的,只需要两步

  1. 配置定时策略
  2. 将任务添加到 FlushData 中
@iohao iohao added enhancement;功能增强 Function enhancement;功能增强 Support extension;可扩展 Support extension;可扩展 May support;打算支持,但不紧急 Maybe, but not necessarily;后续版本计划提供的功能 labels May 30, 2024
@iohao iohao self-assigned this May 30, 2024
@molin7596
Copy link

molin7596 commented Jun 3, 2024

请问一下 TaskKit 与 spring Schedule + Async + Virtual Thread ,TaskKit 优于Schedule 吗, 还是倾向于 提供给非spring使用

@iohao
Copy link
Owner Author

iohao commented Jun 3, 2024

请问一下 TaskKit 与 spring Schedule + Async + Virtual Thread ,TaskKit 优于Schedule 吗, 还是倾向于 提供给非spring使用

  1. 提供给非 spring 使用
  2. 学习成本更低,1 分钟之内上手。仅需配置 N 分钟同步一次 DB,及 put 的使用
  3. 扩展性强,定制性强,使用的 TaskListener 接口。

关于 TaskListener 任务监听回调接口,可阅读 TaskKit (yuque.com)

TaskListener 是与时间相关的任务监听回调接口。使用场景有:一次性延时任务、任务调度、轻量可控的延时任务、轻量的定时入库辅助功能 ...等其他扩展场景。


TaskKit 优于 Schedule 吗

两者解决的业务场景不一样,无法比较;除非给出一个特定的业务场景,才能相互比较。

实现方面,TaskKit 与时间相关的统一由 HashedWheelTimer 处理。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement;功能增强 Function enhancement;功能增强 May support;打算支持,但不紧急 Maybe, but not necessarily;后续版本计划提供的功能 Support extension;可扩展 Support extension;可扩展
Projects
None yet
Development

No branches or pull requests

2 participants