Skip to content

Instantly share code, notes, and snippets.

View FZambia's full-sized avatar

Alexander Emelin FZambia

View GitHub Profile
@FZambia
FZambia / chi.go
Created February 21, 2024 11:20 — forked from alexaandru/chi.go
Chi-like syntactic sugar layer on top of stdlib http.ServeMux
// Chi-like syntactic sugar layer on top of stdlib http.ServeMux.
package main
import (
"net/http"
"slices"
)
type (
middleware func(http.Handler) http.Handler
@FZambia
FZambia / pool.go
Created October 15, 2020 16:53
Goroutine (worker) pool for Go language
package gpool
import "context"
// Job represents function to be executed in worker.
type Job func()
type worker struct {
jobs chan Job
stop chan struct{}
@FZambia
FZambia / main.go
Last active August 15, 2023 04:36
Experimenting with QUIC and WebTransport in Go, see original post: https://centrifugal.github.io/centrifugo/blog/quic_web_transport/
package main
import (
"context"
"crypto/tls"
"encoding/binary"
"errors"
"io"
"log"
"net/url"
@FZambia
FZambia / index.html
Created June 20, 2020 18:05
Centrifuge introduction example source code
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="https://rawgit.com/centrifugal/centrifuge-js/master/dist/centrifuge.min.js"></script>
</head>
<body>
<script type="text/javascript">
const centrifuge = new Centrifuge('ws://localhost:8000/websocket');
function drawText(text) {
const div = document.createElement('div');
@FZambia
FZambia / api.swagger.json
Created May 19, 2020 21:02
API Swagger JSON
{
"swagger": "2.0",
"info": {
"title": "api.proto",
"version": "version not set"
},
"consumes": [
"application/json"
],
"produces": [
@FZambia
FZambia / logo.js
Created May 13, 2020 21:45
Logo javascript canvas
(function() {
'use strict';
window.addEventListener('load', function() {
var canvas = document.getElementById('canvas');
if (!canvas || !canvas.getContext) {
return false;
}
function rand(min, max) {
@FZambia
FZambia / release.txt
Created May 8, 2020 12:38
Centrifuge v0.8.0 release diff vs v0.7.0
$ gorelease -base=v0.7.0 -version=v0.8.0
github.com/centrifugal/centrifuge
---------------------------------
Incompatible changes:
- (*Client).Send: changed from func(github.com/centrifugal/protocol.Raw) error to func([]byte) error
- (*MemoryEngine).AddHistory: changed from func(string, *github.com/centrifugal/protocol.Publication, *ChannelOptions) (*github.com/centrifugal/protocol.Publication, error) to func(string, *github.com/centrifugal/protocol.Publication, *ChannelOptions) (StreamPosition, bool, error)
- (*Node).Disconnect: changed from func(string, bool) error to func(string, ...DisconnectOption) error
- (*Node).History: changed from func(string) ([]*github.com/centrifugal/protocol.Publication, error) to func(string, ...HistoryOption) (HistoryResult, error)
- (*Node).Publish: changed from func(string, []byte, ...PublishOption) error to func(string, []byte, ...PublishOption) (PublishResult, error)
- (*Node).Unsubscribe: changed from func(string, string) error to func(string, string, ...UnsubscribeOption
@FZambia
FZambia / functions.js
Created March 3, 2020 18:57
Artillery io Centrifugo
This file has been truncated, but you can view the full file.
module.exports = { subscribe };
var items = [
{
token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI5YmRhNWNlYy02MzRiLTQ2NWItOTNmMC00MTc5MWNmNTAyYzgifQ.DSJ1n4Zrf7CGSX15em3FWrL_4hbJXUFr_lebSQvU7go',
channel: 'notifications#9bda5cec-634b-465b-93f0-41791cf502c8'
},
{
token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJiYWU3MTQxNy05MmVhLTRjMjMtODNkZi1mMDJlNTA2NTY0NmQifQ.lmfVqgTrGxX3Wy8nPC30852AbWnVUD9iJrWR209Qvw0',
channel: 'notifications#bae71417-92ea-4c23-83df-f02e5065646d'
package main
import (
"encoding/json"
"fmt"
"log"
"math/rand"
"net/http"
"os"
"os/signal"

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.