Quần Cam Blog

Euruko 2017 Notes

Vừa rồi mình đi Euruko 2017 ở Budapest, một số bài nói cũng khá thú vị nên mình sẽ note lại ở đây.

Tổng quát

Euruko 2017 có vẻ là Ruby conference hay nhất mà mình từng tham dự từ trước đến nay. Các đề tài năm nay khá đa dạng và thuộc về nhiều mảng khác nhau, từ những đề tài thực dụng như chia sẻ kinh nghiệm maintain một legacy app đến những đề tài thiên về khoa học máy tính như làm sao để dự đoán sự biến thiên về hiệu suất của một app.

Dàn diễn giả cũng khá hoành tráng và dàn trải cả về kinh nghiệm lẫn giới tính (đủ 3 giới), với Matz, cha đẻ của Ruby và Charles Nutter (maintainer của JRuby) đảm nhận keynote. Nói theo kiểu Tây là rất inclusive.

MJIT

Đây là bài nói keynote của bác Matz, MJIT là viết tắt của MRI JIT. MJIT là một trong những hướng đi để giúp Ruby 3 đạt được mục tiêu Ruby 3x3 (Ruby 3 nhanh hơn Ruby 2 gấp 3 lần).

Matz có giải thích một chút về khái niệm Ruby 3x3:

  1. Chuẩn mốc để so sánh tốc độ là Ruby 2.0, vì mỗi bản Ruby mới được phát hành mỗi mùa Nô-en đều được tăng tốc khoảng 5-10%.
  2. Một trong những công cụ benchmark của Ruby là Optcarrot, và họ không làm micro-benchmark.

Theo Matz thì MJIT là một hướng đi hết sức khả quan, được phát triển bởi bác @vnmakarov, một maintainer của GCC. Các bạn có thể xem qua nhánh MJIT tại đây.

Theo cách mình hiểu thì hướng của MJIT là:

Ruby code
---(MJIT)---> precompiled headers ---> optimized C code
---(GCC)---> machine code

và giới thiệu thêm RTL sẽ là Ruby Virtual Machine mới thay cho YARV. Đây là một hướng đi hết sức triển vọng, benchmarking với Optcarrot cho MJIT + RTL thì tốc độ nhanh hơn cả JRuby.

Hy vọng về một ngày mai tương sáng cho anh em Ruby.

Digital Ocean charge tiền bạn như thế nào?

Người đại diện DO mở đầu bằng cách giới thiệu đoạn code tính tiền người dùng của họ. Mình không nhớ rõ chi tiết đoạn code lắm (sẽ xem lại khi họ ra video và cập nhật lại nếu sai). Đại khái là với mỗi user:

def bill_user(user)
  usage = calc_usage(user)
  amount = calc_amount(usage)
  success = check_user_credit(user)
  send_email(amount, user)

  if success
    charge_credit(amount, user)
  else
    charge_credit_card(amount, user)
  end
end

Và đến mỗi tháng chạy billing, đoạn code này ngốn chừng 1-2 ngày. Điều này rất không tốt nên họ quyết định optimize nó lại.

Cách làm của họ khá đơn giản, không có gì là fancy cả. Với mỗi hàm ở trên, họ biến nó thành một job trên Sidekiq, rồi chạy async. Ví dụ như sau:

class SendEmailJob
  include Sidekiq

  def perform(success, amount, user)
    send_email(success, amount, user)
    # schedule next step

    if success
      ChargeCreditJob.perform(amount, user)
    else
      ChargeCreditCardJob.perform(amount, user)
    end
  end
end

Kết quả họ đạt được là khá mĩ mãn.

  • Thời gian chạy giảm xuống chỉ còn 8 tiếng.
  • Việc phân tán task ra nhiều máy chủ (distributed systems) giúp việc scale dễ dàng hơn. Sidekiq scale thế nào thì họ scale như thế đấy.

Và có thể bạn đã đoán ra, cách làm này tồn tại lỗi race condition (thật ra tên bài nói của họ là Distributed Systems: Your Only Guarantee Is Inconsistency).

Ví dụ như trong quãng thời gian email đang được gửi thì user nạp thêm credit vào tài khoản, thế là user quay sang phàn nàn Vì sao các ông trừ tiền thẻ tín dụng của tôi khi tôi có credit trong tài khoản?.

Họ đã fix lỗi ở trên bằng cách chèn thêm ngày tháng vào email được gửi, dạng như:

Kính gửi ông nọ bà kia,

Hôm nay 16/10/2017 12:34:56, số credit của ông/bà là $1.7, không đủ để thực hiện giao dịch này, nên chúng tôi sẽ tiến hành trừ qua thẻ tín dụng.

Theo mình nghĩ là race condition vẫn tồn tại trong đoạn code ban đầu, chỉ là khi chạy synchronize thời gian chưa đủ để chúng nó race.

Bài học rút ra

  • Chú ý các lỗi race condition khi làm việc với async.
  • Chèn thêm ngày tháng làm “bằng chứng thép”.
  • Old-school tool hay shiny new tool cũng được, miễn là được việc.

Bonus

Bonus thêm cho các bạn một số tấm hình hậu conference hành trình mình lê lết từ Hungary qua Áo.

Hungary - Austria


NGUY HIỂM! KHU VỰC NHIỀU GIÓ!
Khuyến cáo giữ chặt bàn phím và lướt thật nhanh khi đi qua khu vực này.
Chức năng này hỗ trợ markdown và các thứ liên quan.

Bài viết cùng chủ đề

Six confusing features in Ruby

In this post I am trying to point out some Ruby features you might want to use with a lot of caution.

Bundler Gotcha

A few days ago I encountered a strange behavior of Bundler so this post notes down how my experience with it was.

Five Rails Gotchas

It’s undeniable that Rails is a great framework to speedily build up your application. However, despite of its handiness, like other frameworks, Rails has its own flaws and is never a silver bullet. This post is going to show you some of the gotchas (or pitfalls you name it) I encountered while working with Rails.