2011-06-27 23 views
11

Ghi nhật ký đồng bộ phát sinh một hình phạt hiệu suất lớn vì nó có thể bị chặn. Có một thư viện Ruby độc lập mà không ghi nhật ký không đồng bộ (log4r dường như không)? Tôi có thể sửa đổi bộ ghi thư viện chuẩn để đăng nhập không đồng bộ không? Tôi đang tìm kiếm một cái gì đó giống như của log4j AsyncAppender - nhưng tốt hơn là một thực hiện mà làm cho việc sử dụng các khối mã của Ruby để chuyển càng nhiều công việc cho các chủ đề nền càng tốt.Có thư viện ghi nhật ký không đồng bộ cho Ruby không?

+0

Are 'thông dịch ruby' những ngày này vẫn còn khá ham-xâu thành chuỗi khi nó liên quan đến mã đa luồng? Vẫn còn một thông dịch viên khổng lồ khóa rằng mã nguồn gốc đơn Ruby có nguồn gốc duy nhất không? Tôi rất tò mò bởi vì, trừ khi bạn đã sử dụng một khung công tác như [eventmachine] (http://rubyeventmachine.com/) để buộc _all_ IO của bạn không đồng bộ, bạn có thể không thực sự thấy bất kỳ lợi ích nào từ việc thực hiện việc ghi nhật ký không đồng bộ . – sarnold

+0

Tôi thường sử dụng JRuby, do đó, có chủ đề Java thực (tôi nghĩ) ... –

+0

ooh;) đó là một lý do thuyết phục để xem xét sử dụng JRuby, sau đó. Cảm ơn. – sarnold

Trả lời

15

tôi biết bạn nên không thực sự trả lời câu hỏi của riêng mình, nhưng có vẻ như mọi thứ đều dễ dàng trong ruby:

require 'thread' 
require 'singleton' 
require 'delegate' 
require 'monitor' 

class Async 
    include Singleton 

    def initialize 
    @queue = Queue.new 
    Thread.new { loop { @queue.pop.call } } 
    end 

    def run(&blk) 
    @queue.push blk 
    end 
end 

class Work < Delegator 
    include MonitorMixin 

    def initialize(&work) 
    super work; @work, @done, @lock = work, false, new_cond 
    end 

    def calc 
    synchronize { 
     @result, @done = @work.call, true; 
     @lock.signal 
    } 
    end 

    def __getobj__ 
    synchronize { @lock.wait_while { [email protected] } } 
    @result 
    end 
end 

Module.class.class_exec { 
    def async(*method_names) 
    method_names.each do |method_name| 
     original_method = instance_method(method_name) 
     define_method(method_name) do |*args,&blk| 
     work = Work.new { original_method.bind(self).call(*args,&blk) } 
     Async.instance.run { work.calc } 
     return work 
     end 
    end 
    end 
} 

Và ví dụ đăng nhập của tôi:

require 'Logger' 
class Logger 
    async :debug 
end 
log = Logger.new STDOUT 
log.debug "heloo" 

Là giá trị trả về công việc, bạn có thể sử dụng tính năng này cho mọi thứ:

require "test/unit" 
class ReturnValues < Test::Unit::TestCase 
    def do_it 
    5 + 7 
    end 
    async :do_it 
    def test_simple 
    assert_equal 10, do_it - 2 
    end 
end 
+0

Tuyệt vời. Tính chất biểu cảm của Ruby liên tục làm tôi ngạc nhiên. Bạn đã đề cập bằng cách sử dụng JRuby vì vậy bạn có khả năng có chủ đề thực sự nhưng bạn cũng đang sử dụng rất nhiều phép thuật ruby ​​năng động như vậy làm thế nào cũng JRuby đối phó với tất cả các thủ thuật năng động? Thật tuyệt khi thấy một số điểm chuẩn với JRuby và MRI cạnh nhau. – davidk01

+0

Mã đẹp! Bạn có thể sử dụng sợi/eventmachine tốt hơn. Chủ đề sẽ thực hiện công việc, nhưng chúng nặng hơn nhiều trong MRI (và trong tương lai ở JRuby) và yêu cầu quản lý và đồng bộ hóa. Tôi nghĩ rằng đã có một máy tập tin sự kiện streamer mà có thể được gần với những gì bạn muốn: http://stackoverflow.com/questions/2749503/what-is-the-best-way-to-read-files-in-an -eventmachine-based-app –

2

Không kinh nghiệm cá nhân với điều đó:

Các Swiftcore Analogger thực hiện một nhanh hệ thống không đồng bộ khai thác gỗ cho các chương trình của Ruby cũng như thư viện khách hàng để gửi tin nhắn đăng nhập đến Quá trình tương tự.

Trình tương tự sẽ chấp nhận nhật ký từ nhiều nguồn và có thể có nhiều đích ghi nhật ký. Hiện tại, việc đăng nhập vào một tệp, tới STDOUT hoặc đến STDERR được hỗ trợ. Bản sửa đổi trong tương lai cũng có thể hỗ trợ đăng nhập vào một điểm đến cơ sở dữ liệu .

Trình tương tự phụ thuộc vào EventMachine (http://rubyforge.org/projects/eventmachine) để cung cấp khung cho truyền thông mạng, mặc dù EM là không được sử dụng cho thư viện khách hàng.

+0

Điều này dường như thực hiện việc ghi nhật ký không đồng bộ trong một quy trình riêng biệt hoàn toàn - tôi muốn ghi nhật ký trong quá trình (chỉ trên một luồng khác) –

1

Việc xây dựng trong lớp Logger đã được chủ đề an toàn

+0

Tôi muốn các thông điệp tường trình được ghi vào đĩa trên một chủ đề riêng biệt, vì vậy nếu khối IO nó không làm chậm chủ đề chính của tôi. –

Các vấn đề liên quan