[email protected]:~$

  • Celluloid中的Atom Mode与锁

    Celluloid默认是Atom Mode执行的, 这种模式下可以中断当前执行的任务 先执行下一个 Celluloid提供了一个sleep方法,在Actor内部调用sleep时会中断当前Fiber并且用timer异步来恢复 def before_suspend(task) @timers.after(@interval) { task.resume } end 当中断当前的TaskFiber时,Actor即可处理下一个message,被中断的message等待timer去恢复自身 def task(task_type, method_name = nil, &block) if... .... else @task_class.new(task_type, &block).resume#中断fiber时从此处返回 end end 我们在Actor上的每次调用都是一个独立Fiber Actor 线程是一个worker,来运行多个Fiber,个人感觉这里有点矛盾,Celluloid把多线程程序,变成了多Fiber程序,不同的Fiber很有可能并发访问同一个变量 而exclusive就是Celluloid中的Fiber的锁。actor本身就是消除锁的,而现在却又引入了一个新的锁。 不过实际写过Celluloid程序后,感觉还是不要对这个锁太担心的,实际中只有中断时(调用sleep)才会插入新的fiber,而我们在写需要同步执行的代码时 一般的正常人类是不会在其中插入个sleep的,如果必须确定代码的同步 则要把代码写在exclusive块中(一般不需要,exclusive作用是阻止在本块中Fiber的中断) 这种机制虽然带来了少许的复杂性但是 绝大多数情况下我们无需知道这种机制也可正常的运作程序 即使用到exclusive, 也只是很简单的应用 可以更加有效率的利用线程 Celluloid把任务和worker之间隔离开,之后可能会把thread和actor也进行抽象分离,这样增加了灵活性和效率, 不过随之也带来了复杂性, 其中得失还是很难说清的

  • Celluloid::Actor结构与调用过程

    ruby是面向对象语言,但是Celluloid做到了无需更换代码,仅在类中include Celluloid就可以进行面向Actor编程 class A include Celluloid def foo puts "bar" end end 此时A已经代表一个Actor类 a = A.new a.class #A a.class.ancestors #[A, Celluloid::InstanceMethods, Celluloid, Object, PP::ObjectMixin, Kernel, BasicObject] a.is_a? A #true A === a #true of course! a.is_a? Celluloid #true Celluloid === a #false W..T..F?? wtf? a是A的实例,我们的测试可以通过 但是当我们用Celluloid来测试时a.is_a?和Celluloid.===结果不一致 ###why? 因为a并不是A的实例 a.class #A...

  • ActiveSupport::Concern学习

    ##为什么需要使用ActiveSupport::Concern active_support/concern.rb中已解释的很清楚 简要的总结下 ———————— module Bar需要在included时调用module Foo的方法 此时需要在class C中include Bar就需要先include Foo 但是像这样使用的时候需要关心依赖问题是很不爽的,我们希望使用Bar则include Bar即可,不应该再去管Bar的依赖问题 module Bar include Foo #..... end 这样我们就可以只include Bar而不需要关心Foo 但这样也有问题,Foo可能在included中需要class C。但是现在这样Foo在included中取到的实际是Bar,并不是C ActiveSupport::Concern可以神奇的帮我们解决这个问题,保证Bar的执行没问题,并且使用者不需要关心Foo 只需把def self.included换成Concern提供的include方法即可 Concern源码 module Concern #被extend时会对extend其的module设置一个实例变量用于储存依赖数组 def self.extended(base) #:nodoc: base.instance_variable_set("@_dependencies", []) end #被include时会在include其的module中追加依赖self #如果include的对象中不包含@_dependencies(即没有extend Concern) #则表明该对象为正确的include目标,在该对象上include所有本module依赖的module,extend ClassMethods。最后调用'included'可以保证避免included中的依赖问题 def append_features(base) if base.instance_variable_defined?("@_dependencies") base.instance_variable_get("@_dependencies") << self return false...