• 浅谈尾递归 at 2018年06月05日

    请教一个问题, 既然尾递归可以 一定程度 上解决递归导致的内存泄漏问题, 为什么这个参数没有默认开启呢? 尾递归的开销是什么呢?

  • 数据结构之 HashMap at 2018年06月04日

    明白了, 谢谢楼主分享.

    一致性哈希算法很赞, 学习了新的知识, 非常感谢!

  • 数据结构之 HashMap at 2018年06月03日

    在Ruby中some_hash[some_key] = some_value这种哈希操作虽然有多个步骤(取哈希值=>做映射=>再赋值),但整个操作在底层是由C语言实现的,而GIL会保证这段C代码执行的原子性。这里面并没有真正的并发。

    楼主您好,请问这块有源码分析吗?您说的GIL,只是用不到多核而已,并发并不是指用到了多核才是并发。

    ruby的并发同样涉及到上下文切换,所以并发中的竞争问题(race condition)同样存在的。

    GIL 不意味着 线程安全

    建议可以看下 working with ruby threads 第五章的内容

  • 感谢分享, 我们会参考一下.

    我们在设计的时候会考虑几点:

    1. Sidekiq Worker不需要去管理job的状态, 也就是并发的任务本身对job状态是无感知的, 也没有状态的概念
    2. 工具是通用的, 不仅仅在导出场景, 任何批量多任务处理, 都可以使用.
    

    在新版本的Rails中, 有ActiveJob, 里面的callback可以做到这些功能, 但是我们并未在上面做扩展, 因为

    • 我们使用的Rails版本太低了(<5)
    • 我们希望这个更底层一些, 所以选择使用了Sidekiq的Middleware

    您说的这个也是一个解决方案, 但是个人觉得太偏向于某一种场景了, 如果换一种场景的话, 可能又得再实现一遍; 建议可以抽离出一个插件, 做成一个执行引擎, 相信从可读性和实用性而言会更好一些.

  • 嗯, 是的.

    这个文档解决的问题, 是希望耗时的任务 高性能并且状态可跟踪, 跟高可用关系不大, 所以没有考虑自己实现 RPOPLPUSH

  • 是的,您说得对。

    但是这一块是专门为sidekiq定制的,数据结构设计还包括 sidekiq_class 等,这些其实也可以用在 kafka 中。

  • Pro版本使用到了, 用来做高可用, 保证数据不丢的.

    Sidekiq Pro offers an alternative fetch strategy, super_fetch, for job processing using Redis' RPOPLPUSH command which keeps jobs in Redis.

    wiki: 这里

  • 是的, 我们是这样做的.

    job_id 在执行

    job_id = AWorker.perform_async(params)
    

    的时候, 已经生成了. 但是需要利用 Sidekiq 的 Middleware, 去更新这个 job 的执行情况.

    对于前端, 只需要轮询状态就可以了.

  • each_slice 这块我理解得不对, 我们在实际业务的做法跟您所说的是一致的.

  • 因为我们需要一个job的状态, 以及业务失败时, 这个job的错误信息.

    如下面的信息:

    { status: failed, message: "发生错误: 您的资质不满足报名条件" }
    

    我们是通过 raise NormalException 来中断任务, 并将信息存储在异常中的.

    所以说, 我们需要通过job_id, 来找到这个job, 访问这个job的状态(status), 并拿到业务逻辑的错误信息(message)

    这儿其实跟 Erlang 的 Let It Crash 有点儿像, 但是使用上会稍微简单一点.

    另外, 所有跟job相关的参数, 状态信息也都会入到数据库. 因为Sidekiq 的 任务是使用 Redis#brpop 命令的, 消费了之后, 消息就没有了, 就找不到这个 job 了.