It's relatively easy to scale out stateless web applications. You often only need a reverse proxy. But for those stateful web applications, especially those applications that embeds websocket services in them, it's always a pain to distribute them in a cluster. The traditional way is introducing some external services like Redis to handle pubsub, however, in such way, you often need to change your code. Can Erlang/Elixir, the "concurrency oriented programming languages", best other languages in this use case? Has Phoenix framework already integrated the solution of horizontally scaling websocket? I'll do an experiment to prove (or disprove) that.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'dart:async'; | |
| import 'package:flutter/material.dart'; | |
| import 'package:bloc/bloc.dart'; | |
| import 'package:flutter_bloc/flutter_bloc.dart'; | |
| void main() => runApp(MyApp()); | |
| class MyApp extends StatelessWidget { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| brew install caddy mkcert nss dnsmasq | |
| mkcert -install | |
| mkcert '*.app.test' '*.cdn.test' | |
| # rename the certs and move them under /usr/local/etc/caddy/certs | |
| cat <<EOF > /usr/local/etc/caddy/Caddyfile | |
| *.app.test:443, *.cdn.test:443 { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type socket | |
| type event | |
| type config = { | |
| reconnect: bool; | |
| debug: bool; | |
| timeout: int; | |
| interval: int | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Making promises | |
| */ | |
| let okPromise = Js.Promise.make((~resolve, ~reject as _) => [@bs] resolve("ok")); | |
| /* Simpler promise creation for static values */ | |
| Js.Promise.resolve("easy"); | |
| Js.Promise.reject(Invalid_argument("too easy")); |
Concurrency is a domain I have wanted to explore for a long time because the locks and the race conditions have always intimidated me. I recall somebody suggesting concurrency patterns in golang because they said "you share the data and not the variables".
Amused by that, I searched for "concurrency in golang" and bumped into this awesome slide by Rob Pike: https://talks.golang.org/2012/waza.slide#1 which does a great job of explaining channels, concurrency patterns and a mini-architecture of load-balancer (also explains the above one-liner).
Let's dig in:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # The MIT License | |
| # SPDX short identifier: MIT | |
| # Further resources on the MIT License | |
| # Copyright 2017 Denis Gladkikh (https://www.outcoldman.com/en/archive/2017/07/19/dbhist/) | |
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |
| # of this software and associated documentation files (the "Software"), to deal | |
| # in the Software without restriction, including without limitation the rights | |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "content_scripts": [ | |
| { | |
| "matches": ["http://*/*", "https://*/*"], | |
| "js": ["inject.js"], | |
| "all_frames": true | |
| } | |
| ], | |
| "web_accessible_resources": [ | |
| "content.js" |