Friday, March 03, 2017
finished Programming Elixir 1.2
the otp part is very basic, I actually want to know more about different kind of supervisor behaviours.
elixir is nice but I still prefer clojure for now.
funny that I saw this post on reddit: Elixir or Clojure?, it's a good summary of two languages.
I like ruby has some special options for reading from stdin:
-n
will wrap your codes with while gets(); ... end
, for example:
$ cat /etc/passwd | ruby -ne 'puts $_.split(":").first'
-a
autosplits $_
to $F
, use -F
to specify pattern:
$ cat /etc/passwd | ruby -F: -ane 'puts $F.first'
-p
is like -n
, but puts
$_
autometically:
$ cat /etc/passwd | ruby -F: -ape '$_="#{$F.first}\n"'
-r
to require library
reading Text Processing with Ruby
reading file with ruby is simple and easy, much better than php's syntax.
for reading large file, use mmap, this is a good tutorial for it: Java NIO - Memory-Mapped Files with MappedByteBuffer
clojure has thebusby/iota library to deal with huge files.
reading Clojure Programming Cookbook too.
I found myself know too little clojure, this book taught me a lot.
Specter - Clojure's missing piece hits 1.0
, looks powerful but I haven't try yet.
my current project needs to parse a big nested json, I think specter can help.
halgari/odin: An embedded extensible logic DSL for Clojure. is another library may be useful for me.
docker, my colleage suggests me Kitematic, a GUI tool for docker.
it's so easy to manage containers with kitematic, if image's dockerfile
has VOLUME
mount point, you can map a local directory via GUI. but if not, you'll need to rebuild it or enter the VM to start the container manually with -v
option.
overall it's an excellent tool for local development with docker.
Saturday, March 04, 2017
I'll rewrite dev news page in order to make it faster.
I also want deep dive into redis and postgresql, not just basic, more in-depth study.
will start from redis and go through their Redis documentation page, it has lots of details.
Monday, March 06, 2017
read gz
files inside irb
:
irb> require 'zlib'
irb> Zlib::GzipReader.open("access.log.2.gz") { |z| z.readlines.grep(/assets/).map{|x| x.split('"')[1]} }
ruby provides richer funcions to parse/filter data, and repl can save previous results.
Tuesday, March 07, 2017
aws s3 was down in us-east
region, it reminds people s3 is the biggest single point of failure.
found an interesting implementation from this comment, regarding Dodging S3 Downtime With Nginx and HAProxy:
Heads up a simple yet production ready NGINX location block to proxy to a public s3 bucket looks like:
# matches /s3/*
location ~* /s3/(.+)$ {
set $s3_host 's3-us-west-2.amazonaws.com';
set $s3_bucket 'somebucketname'
proxy_http_version 1.1;
proxy_ssl_verify on;
proxy_ssl_session_reuse on;
proxy_set_header Connection '';
proxy_set_header Host $s3_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_buffering on;
proxy_intercept_errors on;
resolver 8.8.4.4 8.8.8.8;
resolver_timeout 10s;
proxy_pass https://$s3_host/$s3_bucket/$1;
}
Adding NGINX caching on-top of this is pretty trivial.
Also, heads up, in the directive proxycachepath, they should consider enabling "usetemppath". This directive instructs NGINX to write them to the same directories where they will be cached. We recommend that you set this parameter to off to avoid unnecessary copying of data between file systems. usetemppath was introduced in NGINX version 1.7.10 and NGINX Plus R6.
use_temp_path=off
Also, they should enable "proxycacherevalidate". This saves on bandwidth, because the server sends the full item only if it has been modified since the time recorded in the Last-Modified header.
proxy_cache_revalidate on;
Friday, March 10, 2017
learned a few new linux tricks:
my old colleague told me long time ago time
is not the same as /usr/bin/time
, there is a new article talks about this
I learned you can type \time
(will search time
in your $PATH
) to not use the built-in time
the ‘ escape character just make it a different from
time for
bash, you can use
t\ime` as well, same.
it's helpful that sometimes you don't want to use alias commands (like turn off output colors), you can use \ls
to call /bin/ls
instead of using your ls
alias.
when you forgot use nohup
for a long running command, you can ctrl-z
to suspend it, bg
it, and remember to disown
it as well.
molly-guard
is a command prevants you accidentially reboot/shutdown your machine. check example of it
Calling Go Functions from Other Languages is an interesting read.
now I know I can call a go program in java, and of course, in luajit
.
kotlin releases version 1.1, coroutines (async
/await
, yield
) is nice.
borrowed Reactive Web Applications from local library.
actually I read the first chapter two years ago, but chapter 1 covers many history/concepts, I don't think I had the knowledge to understand them back then.
I really enjoy it and I need to read it again. (can download it free from official manning site)
rest of the book is about play and akka, I kinda interested in both but I don't want to touch scala, so I think it will be a very quick read.
recently I have the same problem as Wrangling State In Clojure
I used to use atom
for common arguments shared between few functions. calling function is easier (fewer arguments), but quite difficult to test.
I switched to more explicit arguments passing, but it reminds me I need a deeper knowledge about Destructuring in Clojure
I read Clojure, The Good Parts again, this is gold:
Most of the time when using atoms, they should not be def at the top level. They should be returned from constructor functions, or stored in Component.
and the use of :aliases
in project.clj
(for lein
):
{:aliases "build-foo" ["run" "-m" "rasterize.build.foo/build-foo"]}
finished reading Clojure Programming Cookbook, I learned quite a lot from it.
clojure really is a deep language, I kept learning new things from different people different books, it's lots of fun.
I also just tried Nightlight, by adding this to your profiles.clj
:
{:user {:plugins [[nightlight/lein-nightlight "1.6.3"]]}}
you can have a web editor when you run lein nightlight
The System Design Primer provides some flash cards for AnkiDroid, quite useful.
Thursday, March 16, 2017
an good discussion about reading resources: Ask HN: What are some good technology blogs to follow?
found two excellent site from it:
- the morning paper | an interesting/influential/important paper from the world of CS every weekday morning, as selected by Adrian Colyer
- Stratechery by Ben Thompson: On the business, strategy, and impact of technology.
also some other good readings:
- dev.to() => The Practical Dev
- SkillsCasts - Skills Matter
- IT Hare on Soft.ware
- Dribbble - Show and tell for designers
- An Architect's View
Friday, March 17, 2017
using cider for quite a while, but didn't use its debugging function: cider/debugging
need spend some time on it.
Easily Deploy Your Clojure Web Site is the new ebook from author of Clojure for the Brave and True, free to read online.
also reading two books from leanpub:
Read Read-Eval-Print-λove by Michael Fogus, co-author of The Joy of Clojure, free to read online.
ClojureScript Unraveled, nice introduction to clojurescript.
listened to two cognicast:
Paul deGrandis - Cognicast Episode 118
talks about cognitect-labs/vase: Data driven microservices, which uses in-memory Datomic database by default.
and here is a tutorial for datomic: ftravers/datomic-tutorial
and Paul Stadig - Cognicast Episode 113
he wrote a book: Clojure Polymorphism
ctop - concise commandline monitoring for containers is a monitor command for containers, looks very nice.
another tool people recommend: Glances - An Eye on your system
couple more cool tools:
- knqyf263/pet: Simple command-line snippet manager, written in Go.
- Pi-hole™: A black hole for Internet advertisements
some other readings:
- Orbit - Virtual actor framework for building distributed systems
- Beautiful Racket by Matthew Butterick
- Railway oriented programming | F# for fun and profit
- Java 9 new features
- A comment left on Slashdot.
- Lua: A Guide for Redis Users
- Teach Yourself Computer Science
Tuesday, March 21, 2017
this is the most beautiful version of SICP I've seen: Structure and Interpretation of Computer Programs, 2e
saw Introduction to TLA+ by Leslie Lamport
don't know what TLA+ is, but SAM (State-Action-Model) pattern is built on TLA+, and it's for distributed system, worth taking a look.
pretty exciting news: A new way of blogging about Lua
it is using vvanders/wasm_lua: Lua VM running in a WASM environment
so javascript really becomes assembly language of web.
Wednesday, March 22, 2017
I wrote a disown
note above (march 10), but I found another good one today from this thread: Famous ssh moment : ProgrammerHumor
ctrl+z
bg %%; disown %%
%%
is the "current job" (last job stopped in foreground or started in background)
clojure destructuring, this signature can handle quite complex arguments:
(defn foo [x & {:keys [a b] :or {a 1, b 2}}] ...)
when coding with clojure, two things are really difficult: naming and api (function) design. need a lot of thinking to work out a clean one.
I'm reading The Joy of Clojure 2nd Edtion now, from cover to cover.
not to learn clojure but how to code clojure.
Thursday, March 23, 2017
few resource for naming things in clojure:
- How to Name Clojure Functions
- bbatsov/clojure-style-guide: A community coding style guide for the Clojure programming language
- Library Coding Standards
Saturday, March 25, 2017
I've been using more vim recently, learned something new:
cgn
:
search for pattern, then cgn
to replace pattern with text. way better than cw
. gn
visual selects the pattern, so if just want to remove text, use dgn
.
good for bulk edit, can just hit n
for next appearance and .
to repeat the command.
pipe selected text to shell command
insert result from shell command is simple, just hit !!
and enter the command.
when I write new puppet manifests, I will do !!
and apt-cache something
to grab package names, and then I will select and pipe them to awk
to do some parsing:
hit !
after selected text, then enter something like awk -F, '{print $2}'
select result, hit :
, then enter sort
. this uses vim's built in sort
function. to use external command, hit !
and run the command.
insert instead of replace
above piping will replace (filter, in vim's term)
I found that to insert / copy result only is not that simple, undo
/redo
is faster.
but if just preview, can use :w ! cmd
.
visit man page with one key stroke
just hit K
, opens man page of the program under cursor, super nice.
ZZ and ZQ
alternatives to :wq
and :q!
, I can hold shift
and that's more lazy.
and lastly, open vim
and run commands, they don't show up in .bash_history
but of course, emacs can do it easily as well, you just need more fingers:
- insert shell command result, hit
c-u m-!
- pipe selected region to shell command:
c-u m-|
- sort on selected region:
m-x sort-lines
- view man page:
m-x man
(m-x woman
if you don't haveman
in your system, installwoman
package first)
new project needs laravel, "codeigniter is abandoned and shouldn't be use anymore, symfony is too complicated ...", and I need to learn laravel deeply.
I really hate those names, by reading their website you can see these Facades, Artisan, Illuminate, Eloquent, Homestead, Valet, Dusk, Envoy...
and they have Elixir and Mix names as well!! they both to compile assets, however, Mix is built on top of webpack
, and the old verion, Elixir is on top of gulp
...
ok, I'm not going to try to understand these.
codeigniter is really not perfect, but as least it makes sense and gets shit done.
Saturday, March 25, 2017
HelloFresh's Migration to a New API Gateway to Enable Microservices interests me because of some tools they picked (all open sourced):
- statsd for monitoring
- gatling for performance testing
- concourse ci as ci tool
even their api gateway is open sourced: hellofresh/janus
infoq has a series of articles on monolith:
super high quality, highly recommended.
for me, I think if you have different goup of engineers take care of each services, and have a centralized monitoring and building system, that's fine.
otherwise, a waste of efforts.
TruffleRuby is a fork of JRuby, some people tested said it's fast.
found that I didn't have ruby setup for my emacs, so I started with:
first, install two gems, required by robe
package below:
$ gem install pry pry-doc
then in emacs, install robe
package, and add these lines (I use company
):
(add-hook 'ruby-mode-hook 'robe-mode)
(eval-after-load 'company
'(push 'company-robe company-backends))
to use it, m-x inf-ruby
to start a irb
repl, then m-x robe-start
to connect to the it.
optional, install flymake-ruby
package for syntax check, but I want to keep it lightweight, I didn't use it.
Sunday, March 26, 2017
learned a very useful trick from this two articles:
in a boot
repl, you can add new dependencies whenever you want by
(set-env! :dependencies '[[org.clojure/data.json "0.2.6"]])
and you can define a function for it:
(defn deps [new-deps]
(merge-env! :dependencies new-deps))
simply has the sample effect of above line.
(deps '[[org.clojure/data.json "0.2.6"]])
add the deps
function to build.boot
file, and start repl with boot repl
.
this is already very useful, but typing s-exp under repl still sucks ... inf-clojure
to rescue:
install inf-clojure
package in emacs, then add this line to init.el
:
(setq inf-clojure-program "boot -C repl")
now m-x inf-clojure
will start the boot
repl, in any buffer after trigger m-x inf-clojure-minor-mode
can send clojure codes to repl and even have auto-complete...
of course paredit
is there as well, super nice.
Monday, March 27, 2017
When I search for difference between inf-clojure
and cider
, I found cider-scratch
m-x cider-scratch
then m-x cider-jack-in
, you can also have a quick repl without creating a new .clj
file.
it is using boot
already and loaded my ~/build.boot
, I don't know why but it works out of the box, having the same functionality as inf-clojure
.
Tuesday, March 28, 2017
Lumen is a micro-framework also by laravel, which is much better choice for simple apps.
it uses nikic/FastRoute for routing, which not the same as laravel, for example, optional parameters is done by []
:
$app->get('/[{name}]', function ($name = null) use ($app) { ... }
views, this part is confusing, they said views
is removed from v5.2.0
, but added back in v5.2.1
, latest documentation still doesn't have views
section.
however, I tested views
is working at v5.4.5
:
create resources/views/foo.php
, call in route callback:
return view('foo', ['name' => $name]);
I like plain php template rather than blade, so it's good enough for me.
the other feature they removed since v5.1
is sessions, by checking their old commits, you'll need these middlewares enabled in bootstrap/app.php
:
$app->middleware([
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
]);
a simple way to have sessions in latest version is to use Symfony's HttpFoundation Component, it's alreay one of the dependencies of lumen, so no extra setups.
a quick test routes/web.php
:
use Symfony\Component\HttpFoundation\Session\Session;
$app->get('/set', function() use ($app) {
$s = new Session();
$s->start();
$s->set('foo', 'bar');
});
$app->get('/get', function() use ($app) {
$s = new Session();
$s->start();
var_dump($s->get('foo'));
});
I've been thinking about this part as well. nowadays they do sessions in jwt
and using state management tools like redux
, it really not necessary to do server side sessions. I'm an old fashioned guy and I need my server side sessions.
finally for netbeans, there is barryvdh/laravel-ide-helper to generate autocompletion file for lumen
reading Professional Clojure, borrowed from local library.
first chapter is great. after coding clojure for a while, I agree it tells the right way to do clojure. simple is really not easy.
notes are taken here.
Thursday, March 30, 2017
Learn redis the hard way (in production) is a good read.
it have few real-world suggestions:
redis is (mostly) single threaded
however, as redis faq said, usually redis is either memory or network bound, very unlikely CPU becomes bottleneck.
also redis has background (mainly related to disk I/O) jobs assigned to other threads.
it also affects cpu monitoring in a multi-core instance, for example aws:
Redis: Since Redis is single-threaded, the threshold is calculated as (90 / number of processor cores). For example, suppose you are using a cache.m1.xlarge node, which has four cores. In this case, the threshold for CPUUtilization would be (90 / 4), or 22.5%.
BGSAVE
also mentioned here: Redis design patterns for high volume applications
for large datasets, may choose using cron
to trigger BGSAVE
.
multiple databases
antirez admits that multiple databases is a bad idea here
I understand how this can be useful, but unfortunately I consider Redis multiple database errors my worst decision in Redis design at all... without any kind of real gain, it makes the internals a lot more complex. The reality is that databases don't scale well for a number of reason, like active expire of keys and VM. If the DB selection can be performed with a string I can see this feature being used as a scalable O(1) dictionary layer, that instead it is not.
With DB numbers, with a default of a few DBs, we are communication better what this feature is and how can be used I think. I hope that at some point we can drop the multiple DBs support at all, but I think it is probably too late as there is a number of people relying on this feature for their work.
One instance per data context / feature
it's better to avoid one redis uses for all. different feature should have different redis instance with its own config.
connection pool
twitter/twemproxy (aka nutcracker
) is a proxy for memcached and redis made by twitter few years ago.
under ubuntu 16.04, can install by apt-get install nutcracker
it's good practice that you have a proxy to handle connection back pressure.
some extended reading:
- Redis latency problems troubleshooting (must read!)
- Redis latency monitoring framework
- Request/Response protocols and RTT (pipelining)
in order to handle data sets larger than memory, can setup Redis cluster for sharding.
note that you'll have at least 3 nodes to determinte majority of masters.
Redis Sentinel provides HA for redis. sentinel nodes should not be at same nodes as redis (more nodes!)
I wonder if sentinel only handles failover, can I use it as zookeeper? or use sentinel as a general purpose HA tool? (I don't have answer yet)
then I read this question: distributed - zookeeper vs redis server sync - Stack Overflow
learned that there're Physical clustering (pacemaker) and Logical clustering (curator, zookeeper)
continue reading professional clojure:
chapter 3
learned that I can replace http response :body
with parsed data:
(update request :body cheshire.core/decode)
much cleaner than use let
to bind the parsed result to a new var.
the storage backend may vary, the book uses defprotocol
defines common methods and reify
to create object implemented those methods.
I think that's neat.
I still sometimes confuse protocol and multimethods, got a clearer idea after read them couple more times:
defmulti
defines dispatcher for different implementation based on incoming arguments and defmethod
to implement the actual method.
a lot of tests examples in this chapter as well.
chapter 5
a nice way to build an hiccup
element:
(into [:ul] (for ...))
Linkerd-tcp, a lightweight, service-discovery-aware, TLS-ing TCP load balancer.
linkerd is interesting piece of technology, a rpc proxy.
they have some nice concepts like: budget and deadline in retries
I'm waiting for their next article of A Service Mesh for Kubernetes series, which is Retry budgets, deadline propagation, and failing gracefully.
Software Engineering Daily has one episode about it: Scaling Twitter with Buoyant.io's William Morgan
- rpc is a synchronous communication, compare to queue/event is asynchronous.
- service discovery should NOT be the single source of truth.
another book from author of Clojure for the brave and true: Parallel Programming in Clojure with Reducers
not much people mentions reducer since transducer, it will be an interesting read.
there is an article about transducer though: Deep dive into a clojure transducer
even though I didn't touch common lisp anymore, I found Articulate Common Lisp nice, it teaches you how to write Common Lisp in 2017.
networknt/light-java: A fast, lightweight and more productive microservices framework
I saw this framework in a microservices benchmark result, this one is top of the chart with other frameworks written in go.
for vim, this is a must read: Vim Text Objects: The Definitive Guide
usually I'll use t
or f
(like dt"
), from now will use text object.
Friday, March 31, 2017
Clojure/west 2017 videos (schedule) are releasing to ClojureTV channel
I just watched Core.Async in Use - Timothy Baldridge
the bad codes in it is just the way I write clojure! I still learning to think in a functional way.
some code snippets I took from the talk:
resize a batch:
(defn batch [in max-size]
(let [out (chan 1)
xf (comp cat (partition-all max-size))]
(pipeline 1 out xf in)
out))
or
(defn batch-xf [max-size]
(comp cat (partition-all max-size)))
use transducer, the point here is the final fn
to deal with final result. a single exit point.
(def xform (comp cat
(filter #(> % 10))
(take 10)))
(pages xform
conj
(fn [result]
(println "Finished with " result)))
it has enter
, exit
and on-error
part, just like js callbacks
, each function receives context ctx
and do some mutation, like ring middlewares
(defrecord Interceptor [enter exit on-error])
(def pipeline [parse-params encode-body handler])
(defn parse-params-enter
[{:keys [param-string] :as ctx}]
(assoc ctx :params (split-params param-string)))
(defn encode-body-exit
[{:keys [body] :as ctx}]
(assoc ctx :body-string (json/encode body)))
(defn handler-enter
[{:keys [params db-conn] :as ctx}]
(go (assoc ctx :body (<! (get-record (:id params))))))
lastly, I think is the most useful one, dataflow (FRP):
you'll define inputs
and outputs
of each node
, and then connect them together, like a graph structure
I like this pattern the most and will dig deeper into it.
(defn transducer-fn
[xducer]
(let [rf (fn [state msg]
(emit state :out msg))]
(xducer rf)))
(def filter-node {:inputs {:in (transducer-fn
(filter pos?))}
:outputs {:out []}})
also watching Faster Delivery with Pedestal and Vase - Paul deGrandis
I learned fnil function when browsing clojure documentations, I found it is useful.
today I read another article on nil
: The case for and against Clojure predicates returning nil
and some real world experience of clojure: Fourteen Months with Clojure
listened to old The InfoQ Podcast archive, and found some great episodes:
Peter Bourgon on Gossip, Paxos, Microservices in Go, and CRDTs at SoundCloud
two CRDT system:
- Roshi is a large-scale CRDT set implementation for timestamped events.
- weaveworks/mesh: A tool for building distributed applications.
talks about go, Peter Bourgon has some good opnions on why go is good, especially for large teams. and good views on why go prefers no versioning.
Go kit - A toolkit for microservices
another good episode:
Chris Richardson on Domain-Driven Microservices Design
he answers a question bothers me for a long time: why CQRS?
the answer is in a distributed environment, you'll need a place to store and query stuffs, CQRS is the component to do this.
and read Domain-Driven Design, a book from 2003 to help you build better microservice architecture. it makes sense and much better than throw out some buzzwords.
some good articles on this site: White Papers | Redis Labs
Managing Transactions in Redise uses lua script to handle transaction.
in real world of course should do it in mysql or postgresql, but it's fun to try using lua script with redis
Blog Archive
- Newer Entries
- 2017 April
- 2017 May
- 2017 June
- 2017 July
- 2017 August
- 2017 September
- 2017 October
- 2017 November
- 2017 December
- 2018 January
- 2018 February
- 2018 March
- 2018 April
- 2018 May
- 2018 June
- 2018 July
- 2018 August
- 2018 September
- 2018 October
- 2018 November
- 2018 December
- 2019 January
- 2019 February
- 2019 March
- 2019 April
- 2019 May
- 2019 July
- 2019 October
- 2019 November
- 2019 December
- 2020 August
- 2020 September
- 2020 October
- 2020 November
- 2020 December
- 2021 January
- 2021 February
- 2021 March
- 2021 April
- 2021 May
- 2021 June
- 2021 August
- 2021 September
- 2021 December
- 2022 March
- 2022 April
- 2022 May
- 2022 June
- 2022 July
- 2022 August
- 2022 September
- 2022 October
- 2022 November
- 2022 December
- 2023 January
- 2023 February
- 2023 March
- 2023 April
- 2023 July
- 2023 August
- 2023 September
- 2023 October
- 2023 November
- 2023 December
- 2024 January
- 2024 February
- 2024 March
- 2024 April
- 2024 May
- 2024 June
- 2024 August
- 2024 September
- 2024 October
- 2024 November
- Older Entries
- 2017 February
- 2017 January
- 2016 December
- 2016 November
- 2016 October
- 2016 September
- 2016 August
- 2016 July
- 2016 June
- 2016 May
- 2016 April
- 2016 March
- 2016 February
- 2016 January
- 2015 December
- 2015 November
- 2015 October
- 2015 September
- 2015 August
- 2015 July
- 2015 June
- 2015 May
- 2015 April
- 2015 March
- 2015 February
- 2015 January
- 2014 December
- 2014 November
- 2014 October
- 2014 September
- 2014 August
- 2014 March
- 2014 February
- 2014 January
- 2013 December
- 2013 October
- 2013 July
- 2013 June
- 2013 May
- 2013 March
- 2013 February
- 2013 January
- 2012 December
- 2012 November
- 2012 October
- 2012 September
- 2012 August