Rails 구동중에 쓰레드 처리 시 아래처럼 원래 루비 구문인 Thread로 처리할 수 있습니다.
1
2
3
4
5
6
7
8
|
Thread.new do
Rails.application.executor.wrap do
system('ping -c 5 127.0.0.1')
result = Net::HTTP.get(URI.parse("http://127.0.0.1:3000/zfd"))
puts result
end
end
|
다만 이런 쓰레드에 대한 관리를 매번 해줘야한다는 것과 공통적으로 사용되는 쓰레드를 구현하기 위해선 조금 번거로운 부분들이 있습니다. 오늘 이야기드릴 라이브러리는 레일즈에서 쓰레드 사용을 위한 그런 라이브러리입니다.
suckerpunch 입니다.
 |
I am HIT-Library? zz |
What is? & How to use
SuckerPunch는 위에서 이야기드린대로 쓰레드 관련 라이브러리이고, 정확히는 단일 Ruby 프로세스에서의 비동기 처리 라이브러리입니다. 단일 어플리케이션 내부에서 Jobs을 생성하고 관리할 수 있기 때문에 Heroku같은 PaaS 환경에서 메모리나 비용적으로 효율적으로 사용할 수 있습니다.
다만 단일 프로세스 위에서 동작하기 때문에 모체가 되는 프로세스가 재시작되면 당연히 초기화됩니다.
https://github.com/brandonhilkert/sucker_punch
해당 라이브러리는 gem 패키지로 gem install
명령또는 Gemfile 이후 bundle install
로 설치할 수 있습니다.
Install with gem
1
2
|
gem install suckerpunch
|
**
**Gemfile
1
2
|
gem 'sucker_punch', '~> 2.0'
|
설치 후 앱 내부에선 SuckerPunch를 Include로 모듈을 로드하여 구현해주시면 됩니다. 제가 재미삼아 만드는 앱인데, 대략 코드를 보면 이렇습니다. (Rails에요)
**
**controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
def action
@log = Log.new(log_params)
url = log_params["host"]
hwulTest.new.scan_spider(url, @log)
# 아래 hwulTest class에서 객체를 생성하고 멤버함수를 실행합니다.
end
# ... 생략 ...
class hwulTest
include SuckerPunch::Job
# SuckerPunch => Job 모듈을 가져옵니다.
def scan_spider(url, obj)
ActiveRecord::Base.connection_pool.with_connection do
payload = "http://127.0.0.1:8081/JSON/~~~blahblah"
res = HTTP.get(payload).body
res = ActiveSupport::JSON.decode(res)
p res["scan"]
data = obj
data.update(state:true)
data.update(data: res["scan"].to_i)
end
end
end
|
이렇게 했을 때 해당 컨트롤러에서 action 이 호출됬을 때 레일즈 메인 로직은 원하는 구문 처리 후 정상적으로 결과를 리턴해주고, hwulTest로 정의한 기능은 비동기로 백그라운드 처리됩니다.
 |
일해라 job들아! |
Built-In
찾다보니 빌트인도 가능했었네요..
Rails
1
2
|
rails g sucker_punch:job logger
|
**
**Sinatra
1
2
3
|
# app.rb require ‘sucker_punch'
require 'sinatra'
|
Optional
추가적으로 볼만한 옵션은 worker, 와 jabs에 대한 정의입니다.
workers를 지정해주어 처리하는 worker를 조절할 수 있습니다. 디폴트 값으로는 2로 되어있습니다.
1
2
3
4
5
6
7
8
9
|
class LogJob
include SuckerPunch::Job
workers 4
def perform(event)
Log.new(event).track
end
end
|
jobs 갯수도 제한할 수 있습니다.
1
2
3
4
5
6
7
8
9
|
class LogJob
include SuckerPunch::Job
max_jobs 10
def perform(event)
Log.new(event).track
end
end
|