Skip to content

Instantly share code, notes, and snippets.

# frozen_string_literal: true
class SafeHash < Hash
def initialize(namespace)
@namespace = namespace
@lock = Concurrent::ReadWriteLock.new
super
merge!({ @namespace => Concurrent::Map.new })
end
class TBQueue
def initialize size
tvar = Concurrent::TVar
@read = tvar.new []
@write = tvar.new []
@rsize = tvar.new 0
@wsize = tvar.new size
end

Scaling your API with rate limiters

The following are examples of the four types rate limiters discussed in the accompanying blog post. In the examples below I've used pseudocode-like Ruby, so if you're unfamiliar with Ruby you should be able to easily translate this approach to other languages. Complete examples in Ruby are also provided later in this gist.

In most cases you'll want all these examples to be classes, but I've used simple functions here to keep the code samples brief.

Request rate limiter

This uses a basic token bucket algorithm and relies on the fact that Redis scripts execute atomically. No other operations can run between fetching the count and writing the new count.

@benolee
benolee / fiber_sleep.rb
Created February 4, 2019 21:54 — forked from wycleffsean/fiber_sleep.rb
Fiber Sleep
require 'fiber'
require 'concurrent' # gem install concurrent-ruby
Thread.abort_on_exception = true
class Async
def self.perform(&block)
instance = new
instance.instance_eval(&block)
until instance.dispatched.value.zero? do
unless instance.yields.empty?
@benolee
benolee / gist:dfbedcd2793b4a013f10611526d4847f
Created January 13, 2018 04:30
Ruby's performance tuning way
@benolee
benolee / Dynflow bottlenecks.md
Created January 13, 2018 04:27 — forked from ShimShtein/Dynflow bottlenecks.md
Dynflow performance analysis.

break /home/shim/Documents/foreman/dynflow/lib/dynflow/utils.rb:60

Why do we need indifferent_hash while saving?

 "/home/shim/Documents/foreman/dynflow/lib/dynflow/utils.rb:60:in `indifferent_hash'",
 "/home/shim/Documents/foreman/dynflow/lib/dynflow/persistence_adapters/sequel.rb:268:in `extract_metadata'",
 "/home/shim/Documents/foreman/dynflow/lib/dynflow/persistence_adapters/sequel.rb:226:in `prepare_record'",
 "/home/shim/Documents/foreman/dynflow/lib/dynflow/persistence_adapters/sequel.rb:236:in `save'",
 "/home/shim/Documents/foreman/dynflow/lib/dynflow/persistence_adapters/sequel.rb:125:in `save_action'",
@benolee
benolee / socat.md
Created November 17, 2017 17:28 — forked from robbwagoner/socat.md
nginx socket socat
@benolee
benolee / archive.sh
Created September 28, 2017 07:13 — forked from marshallm/archive.sh
Baseline pt-archiver bash script for MySQL
#!/bin/bash
source mysql_access
TODAY=$(date +"%Y-%m-%d_%H%M%S")
CHECK_RETAINER=$(
mysql api_test \
-u$MYSQL_USER \
-p$MYSQL_PASS \
-h$SOURCE_HOST \
--socket=$MYSQL_SOCK \

Debugging ruby performance - Aman Gupta

C, Linux, networks, cpu, and memory usage

  • lsof -nPp <pid>
  • tcpdump
  • write the data to a file, load it up in wireshark
  • strace, trace systems calls and signals (jump into kernelspace)
  • SIGVTALRM, ruby 1.8 every 10msec to switch threads (green threads)
  • posix-spawn instead of fork-exec, check out posix-spawn gem
  • ltrace

– ltrace -c ruby foo.rb # summary mode

@benolee
benolee / curl.md
Last active August 29, 2015 14:06 — forked from btoone/curl.md

Introduction

An introduction to curl using GitHub's API

The Basics

Makes a basic GET request to the specifed URI

curl https://api.github.com/users/caspyin