Rectors에 대해 알아보고 미니 사이드키크를 구축하세요.
랙터란?
Ruby 3.0은 Ractor 클래스를 도입했습니다. 이것은 Ruby의 Actor와 같은 동시 추상화이며, 그 목표는 스레드 안전성 문제 없이 Ruby의 병렬 실행 기능을 제공하는 것입니다.
wikipedia에 따르면 :
The actor model in computer science is a mathematical model of concurrent computation that treats actor as the universal primitive of concurrent computation.
액터는 다음을 수행할 수 있습니다.
The actor model in computer science is a mathematical model of concurrent computation that treats actor as the universal primitive of concurrent computation.
Rector 구현은 아직 안정적이지 않으므로 프로덕션 코드에 사용하지 마십시오. 프로덕션에서 (아직) 사용하지 않도록 확신해야 하는 경우 사용할 때 표시되는 경고를 참조하세요.
warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
랙터 만들기
랙터를 만드는 것은
Ractor.new
를 사용하는 것처럼 간단합니다.ractor = Ractor.new { puts 'Hello Ractor!' }
메시지 수신
메시지를 보내는 랙터에 대한 참조가 있는지 여부에 따라 메시지를 수신하는 두 가지 방법이 있습니다.
메시지를 보내는 사람을 모르는 경우
Ractor.receive
를 사용합니다.message = Ractor.receive
메시지를 보내는 랙터에 대한 참조가 있으면
Ractor#take
를 사용하십시오.message = ractor.take
이러한 메소드 호출은 메시지를 수신할 때까지 차단되므로 절대 보내지 않을 랙터로부터 메시지를 기대하지 마십시오. 그렇지 않으면 프로그램이 영원히 중단될 것입니다.
또한 objects you are sending must be shareable .
메시지 보내기
수신자를 알고 있는 경우:
ractor.send(message)
# or
ractor << message # `<<` is an alias to `send`
그리고 당신이하지 않는 경우 :
Ractor.yield(message)
Ractor.yield
일부 랙터가 메시지를 받을 때까지 차단됩니다.현지 결정
Ractor.new
에 주어진 블록에서 원하는 모든 것을 할 수 있습니다. 공유 개체에 액세스하지 않는 한. 블록 외부에 정의된 변수를 사용하려고 하면 예외가 발생합니다. 여러 랙터 간에 변수를 공유하려면 예를 들어 Ractor::TVar gem 을 사용할 수 있습니다.나중에 사용할 또 다른 흥미로운 방법은
Ractor.select(*actors)
방법입니다. 여러 랙터를 입력으로 사용하고 무언가를 보낼 첫 번째 랙터와 그 출력을 반환합니다.slow_ractor = Ractor.new { sleep 2; Ractor.yield(:too_late) }
fast_ractor = Ractor.new { Ractor.yield(:fast) }
ractor, output = Ractor.select(slow_ractor, fast_ractor)
# output == :fast && ractor == fast_ractor
미니 사이드키크를 만들어보자!
이 조잡한 POC를 사용하면 작업의 병렬 실행을 달성하기 위해 10개의 랙터 풀만 사용할 수 있습니다. 오류 흐름 제어, 통계, 대기열 및 sidekiq를 매우 유용한 프로젝트로 만드는 기타 모든 기능을 처리하지 않습니다.
우리는 다음을 사용하여 간단한 디자인을 만들 것입니다.
WorkerPool
, 랙터 풀 관리 Job
기본 클래스입니다. 목표는 사람들이 모든 풀 로직을 처리하지 않고도 자신의 작업을 쉽게 구현할 수 있도록 하는 것입니다.
작업자 풀
class WorkerPool
attr_reader :ractors
def initialize
@ractors = 10.times.map { spawn_worker }
end
def spawn_worker
Ractor.new do
Ractor.yield(:ready)
loop { Ractor.yield Job.run(Ractor.receive) }
end
end
def self.run(parameters)
ractor, _ignored_result =
Ractor.select(*(@instance ||= new).ractors)
ractor << parameters
end
end
여기에 트릭이 있습니다.
Ractor.yield(:ready)
를 사용할 때 우리는 풀의 랙터가 초기 Ractor.select
가 작동하기 위해 보낼 무언가가 있는지 확인하고 있습니다(차단하고 있음을 기억하십시오).작업 기본 클래스
class Job
def self.process(*args)
WorkerPool.run({ class: self, args: args })
end
def self.run(hash)
case hash
in { class: klass, args: args }
klass.new.process(*args)
end
end
end
인수로 제공할 모든 것은 공유할 수 있어야 합니다.
특정 작업 구현
무언가를 인쇄하는 비동기 작업을 만들고 싶다고 가정해 보겠습니다.
class PrintJob < Job
def process(message)
puts message
end
end
비동기식으로 사용하는 것은 이제 다음과 같이 간단합니다.
PrintJob.process('Hello World!')
결론
Ractor는 Ruby에서 병렬 실행을 위한 새롭고 흥미로운 모델을 소개합니다.
랙터 주제가 흥미롭다면 다음 흥미로운 리소스를 확인하는 것이 좋습니다.
이 게시물이 마음에 들면 awesome weekly tech newsletter 을 확인하십시오. 우리는 정기적으로 최고의 루비 및 자바스크립트 콘텐츠를 공유하고 있습니다!
사진Mark Thompson
Reference
이 문제에 관하여(Rectors에 대해 알아보고 미니 사이드키크를 구축하세요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/doctolib/learn-about-ractors-and-build-a-mini-sidekiq-3ba2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)