Jim Cheung

Sunday, May 01, 2016

clojure's default repl is kinda suck, this library can help: REPL-y: A fitter, happier, more productive REPL for Clojure.

simply add [reply "0.3.7"] you'll have a better repl.

looking for a better way to secure the api client, this is a good guide: The Ultimate Guide to Mobile API Security

using JSON Web Tokens is a popular way, for clojure I heard buddy is a goog security library for clojure.

Tuesday, May 03, 2016

I really enjoy reading Joe Armstrong, here's an article about UDP: A Badass Way to Connect Programs Together

I'm using Type and Speak android app (free with no ads) to read webpages for me, it's very useful for some long articles, too tired staring at a tiny screen.

after reading some Advanced Programming in the UNIX Environment, I kinda interested in going back to programming in c, in a modern way.

I think I'll start with Learn C The Hard Way and continue with 21st Century C

Sunday, May 08, 2016

used ranger for a while, switched back to midnight commander.

here're some common keys for mc

so tmux, mc, w3m and a terminal version emacs, perfect for a netbook.

heard about Skynet 1M threads microbenchmark from this article: Go and Quasar: a comparison of style and performance

I know what quasar has a clojure wrapper: pulsar: Fibers, Channels and Actors for Clojure, it's quite interesting. One book I'm currently reading: Clojure for Java Developers, mentions lightweight thread fiber of quasar.

about the skynet, I did my clojure version, but can't make it to run 1M threads. I can run the go version on the same computer without problem, maybe need some tweaking on jvm.

however, I still like to write in clojure:

(defn skynet [num size]
  (if (= 1 size)
    (async/go num)
    (let [subsize (/ size 10)]
      (->> (range 10)
           (map #(async/go (async/<! (skynet (+ num (* % subsize)) subsize))))
           async/merge
           (async/reduce + 0)))))

(time (async/<!! (skynet 0 100000)))

for async/reduce (or functions like async/into), the channel needs to be closed first.

it's kind of like the lazy evaluation, but I don't know how to force it unless performing a blocking take from it :D

Monday, May 09, 2016

I love courier font. found Courier Screenplay in this article: Which Courier is the Best Courier?

learned a lot from this article: Real World Microservices: When Services Stop Playing Well and Start Getting Real

and as it mentioned:

When Twitter moved to microservices, it had to expend hundreds (thousands?) of staff-years just to reclaim operability.

the dynamic nature of new infrastructures is really difficult to handle.

using the http header to change route to a staging service temporatily is a good idea.

also have the option to manage delegations (using namerd) is super cool: you can send 1% traffics to service v2, increase to 25%, and finally 100% but keep the v1 as a fallback, wow.

however, these kind of services built on top of Kubernetes, Mesos, ZooKeeper ...

usually I'll try new tools on tiny projects, not easy to find a project requires distributed systems.

another good post by Julia Evans: A workshop on strace & tcpdump

basically you can just

tcpdump port 80 -i any -w output.pcap

and use wireshare to diagnose the traffic

reading Release It!, a book published in 2007, even my local library is retiring it, I need to request it from off-site stack.

I feel the beauty of try-with-resources after reading the first chapter.

it's a great book, many things still applies in today's software. for example circuit breakers is the way to do fail fast (Hystrix)

Tuesday, May 10, 2016

an updated version of skynet program:

(defn skynet [up-ch num size]
  (if (= 1 size)
    (async/put! up-ch num)
    (let [down-size (/ size 10)
          down-ch (async/chan 10)]

      (dotimes [n 10]
        (async/<!! (async/go (skynet down-ch (+ num (* n down-size)) down-size))))

      (async/close! down-ch)
      (async/put! up-ch (async/<!! (async/reduce + 0 down-ch))))))
      
(time (let [ch (async/chan)]
        (skynet2 ch 0 1000000)
        (async/<!! ch)))

this one is slightly better, able to run 1M on my laptop, but still take too long.

Saturday, May 14, 2016

continue working on terminal, this page has some nice bitmap fonts

I'm using fixedsys now.

also some cool, but obscure unix tools, and discussion on hackernews

here're some common shortcuts for tmux:

window

|------------+------------------------ |
| prefix + n | next window            |
| prefix + p | next / previous window |
| prefix + f | find window            |
| prefix + w | list windows           |
| prefix + c | new window             |
| prefix + , | rename window          |
| prefix + & | kill window            |
|------------+------------------------|

pane

|-------+-------------------|
| %     | vertical split    |
| "     | horizontal split  |
| space | toggle layouts    |
| o     | swap panes        |
| q     | show pane numbers |
| x     | kill pane         |
| {     | move pane left    |
| }     | move pane right   |
| z     | toggle zoom       |
|-------+-------------------|

Sunday, May 15, 2016

to send commands to multiple tmux panes:

prefix + :, then enter setw synchronize-panes on

set it off when finished.

Tuesday, May 17, 2016

few good podcasts recently:

also read this slide by Monica Beckwith: Way Improved :) GC Tuning Confessions - presented at JavaOne2015

also watched this video from toronto java user group: 2015-10 Runtime Performance Showdown

Ratpack is quite interesting, the sinatra of java.

Wednesday, May 18, 2016

even though after Groovy, I don't really want to invest in learning another jvm lanuage just for syntactic sugar reason.

but Kotlin looks quite nice. finally I decided to give it a try. but I don't want to use the IntelliJ IDEA.

now I just download the Command Line Compiler and play with some scripts.

the syntax actually is simply enough that not requires an IDE.

I'm reading Kotlin in Action free chapter and their language reference.

made a little bash script to start multiple tmux panes at once: (actually using the tmux send-keys ... you can start anything you want in that pane too.)

#!/bin/bash

tmux=/usr/bin/tmux

if [ -z $1 ]
then
    echo what?
    exit 1
fi

if [ -z $TMUX ]
then
    echo "not inside a tmux."
    exit 1
fi

if [ `$tmux list-pane|wc -l` -gt 1 ]
then
    echo "found multiple panes in this window already."
    exit 1
fi

case $1 in
    2) $tmux split-window -h
       $tmux select-pane -t 0
       ;;
    3) $tmux split-window -h
       $tmux split-window -v
       $tmux select-pane -t 0
       ;;
    4) $tmux split-window -v
       $tmux split-window -h
       $tmux select-pane -t 0
       $tmux split-window -h
       $tmux select-pane -t 0
       ;;
    6) $tmux split-window -v
       $tmux split-window -h
       $tmux split-window -h
       $tmux select-pane -t 0
       $tmux split-window -h
       $tmux split-window -h
       $tmux select-pane -t 0
       $tmux select-layout tiled
       ;;
    *) echo what?
       ;;
esac

infoq podcast is back, listened two of them, quick good.

Uber has this interesting project: Ringpop

more details and related topics:

on the Adrian Cockcroft podcast, he mentioned one interesting area is how software/microservices will work on the 2TB large memory instance. all the services (Docker containers) may group back to a single server with low local latency and high speed.

and right after that AWS announced the X1 Instances for EC2, what a coincidence!

talking about coincidence, the book I'm reading: Release It!: Design and Deploy Production-Ready Software the author Michael Nygard is on the latest episode of Software Engineering Radio: SE-Radio Episode 257: Michael Nygard on Clojure in Practice, and talking about Clojure! how nice!

OSCON 2016 is on! check the videos

and Docker open sourced datakit, vpnkit and hyperkit

Thursday, May 19, 2016

a simple makefile when playing kotlin:

KOTLINC=kotlinc
sourcefiles = $(wildcard *.kt)
jarfiles = $(sourcefiles:.kt=.jar)

all: $(jarfiles)

%.jar: %.kt
	$(KOTLINC) $< -include-runtime -d $@

clean:
	rm -f *.jar

a pretty cool list of Programming fonts

I used mp3blaster if I was under terminal, I gave cmus a try today and I love it.

there're quite a lot hotkeys for cmus, but for basic usage:

  1. cmus, then type 5, now you are in the file browser view
  2. navigate to the music folder and hit a, add files to library
  3. hit 1, library view
  4. for quick search, hit 2, then / and type in keywords.
  5. 7 gives you full list of keybindings, / to search

just found out the tpanes command above doesn't work under new tmux 2.1, once created a new pane, the split-window still fired under the original pane instead of new pane. change the split-window command to split-window -h -t 0 will fix that.

under tmux when panes are synchronized, I want some indication, a simple version is like this:

bind-key y setw synchronize-panes on \; rename-window "~~ synchronized ~~"
bind-key u setw synchronize-panes off \; rename-window "-" 

Friday, May 20, 2016

Ilya Grigorik's talk at google I/O 16: Fast and resilient web apps: Tools and techniques for delivering great user experiences, it's really good.

more videos from Google I/O 2016

on the same day OSCON 2016 is held, here are the slides

quite interested in the new Horizon: the realtime, open-source JavaScript backend

it's built by rethinkdb team, another product I wann try. take a look at their Java ReQL command reference, it's like you got orm for free once you installed the server.

Saturday, May 21, 2016

damn I think I love kotlin.

it's nothing wrong with clojure, but it's a totally different thinking between clojure and java

kotlin on the other hand, it's still java, they iterates a collection in same style. static typed is still important I guess.

still playing with it, maybe convert some existing java workers to kotlin see how it goes.

defn is a new podcast on clojure

Sunday, May 22, 2016

finally got a font that I really like: Average Mono

I found it from here: Programming Fonts

continue reading kotlin reference, its classes and objects are quite complicated, I think I'll skip that.

Monday, May 23, 2016

midnight commander allows accessing remote server via ssh as well, simply use alt-c (cd) and enter sh://username@server/path (note, sh://, not ssh://), very nice.

seems not much people coding kotlin in emacs, only find one kotlin-mode.

cider-diet allows you start a cider repl more quickly. I did a quick test it works as described.

that's also why I'm learning kotlin, as an alternative of clojure. it feels so heavy when starting a cider repl, it is just too slow.

Tuesday, May 24, 2016

looking at Upcoming changes in PHP 7.1, keep

also important for clojure: clojure.spec - Rationale and Overview, discussion on Hacker News

Wednesday, May 25, 2016

the blog post about clojure.spec by Rich Hickey: Introducing clojure.spec

a funny comparison: Swift is like Kotlin

Friday, May 27, 2016

don't have time to check yet, but the guide is here: Clojure - spec Guide maybe I'll wait until 1.9 came out.

did a simple task using clojure: a script to manage aws instances in multiple regions. working with repl is such a good experience, combine with macro and core.async, it's so powerful and I really enjoy coding in clojure.

I still have a lot to learn in macro, in fact I skipped all chapters about macro when I read clojure books. I should re-visit those chapters.

a couple notes on core.async:

use timeout:

(alts!! [(timeout 200)
         (go (slurp "https://google.com"))])

and core.async/merge returns a channel, it will close when all source channels closed:

(let [c (async/merge (map #(go (slurp %)) all-urls))]
  (go-loop []
    (when-let [x (<! c)]
      (println x)
      (recur))))

it's better to attach a timeout to it, and usually will need to handle result, timeout and error, but let me work out a simple example first.

Monday, May 30, 2016

using gradle with intellij idea is a pain in the ass, but idea is the only editor has good support for kotlin.

for the application plugin, need to append Kt after the actual kotlin class name.

for example a file src/main/kotlin/my/package/name/something.kt, with package header package my.package.name can add these two lines to build.gradle:

apply plugin: 'application'
mainClassName = "my.package.name.somethingKt"

then gradlew run could able to find your script.

I'm using a pair of re-mapped emacs default prefix keys C-m and C-i (translate to C-x and C-c), but these two keys won't work under terminal, no matter how hard I tried.

under terminal, C-m, C-i are same as RET and TAB keys. translating these two keys to something else is asking for trouble. that's why people are using C-h and C-t if they want to change the prefix keys.

I've been using C-m and C-i for a long time and I don't want to change it. so I just disable the translate when under terminal.

the other problem is (keyboard-translate) not functioning when emacs ran as daemon. the reason is mentioned in this stackoverflow answer.

the final approach is:

(defun usrj/translate-prefix-keys ()
  (when (display-graphic-p)
    (keyboard-translate ?\C-i ?\C-c)
    (keyboard-translate ?\C-c ?\C-i)
    (keyboard-translate ?\C-m ?\C-x)
    (keyboard-translate ?\C-x ?\C-m)))

(usrj/translate-prefix-keys)
(add-hook 'server-visit-hook 'usrj/translate-prefix-keys)

display-graphic-p detect whether it is under terminal, server-visit-hook invoked every time emacsclient is called.

also made another function to run kotlin scripts (.kts):

(defun usrj/run-kotlin-script ()
  (interactive)
  (save-buffer)
  (let ((f (buffer-file-name)))
    (message (format "running %s" f))
    (shell-command
     (format "kotlinc -script %s" (shell-quote-argument f)))))

(add-hook 'kotlin-mode-hook '(lambda ()
                               (local-set-key (kbd "C-c C-r") 'usrj/run-kotlin-script)))

reading Java Network Programming and TCP/IP Sockets in Java, Second Edition at the same time.

maybe because I read this Reverse Engineering A Mysterious UDP Stream in My Hotel, kinda interested in how to dissemble a packet.

find out that Voxxed has pretty good java/jvm articles, for example Benchmarking High-Concurrency HTTP Servers on the JVM is a good one, async not always better. (the article is by Parallel Universe, that's why so many Comsat and Quasar in it, but still a good one)

Tuesday, May 31, 2016

on Housekeeping Puppet Master:

tidy { 'puppet::reports':
  path => '/var/lib/puppet/reports',
  matches => '*.yaml',
  age => '14d',
  backup => false,
  recurse => true,
  rmdirs => false,
  type => 'ctime',
}

the clojure books I read barely mention core.async, but when I check Seven Concurrency Models in Seven Weeks, the whole chapter 6 Data Parallelism is about core.async.

using kotlin to parse yaml files is quite easy, thanks to this article: Kotlin and YAML

I changed a little bit so it can work with generic types:

fun <T> loadYaml(path: Path, datatype: Class<T>): T {
    val mapper = ObjectMapper(YAMLFactory())
    mapper.registerModule(KotlinModule())

    return Files.newBufferedReader(path).use {
        mapper.readValue(it, datatype)
    }
}

for a yaml file like this:

root:
    level1:
      foo: 1
      bar: abc
    level2:
      foo: 2
      bar: xyz

can be parsed with:

data class SampleData(val root: Map<String, LevelData>)
data class LevelData(val foo: Int, val bar: String)

fun main(args: Array<String>) {
    val data = loadYaml(pathToYaml, SampleData::class.java)
}

it's so much easier than working with java and snakeyaml (well, because I don't want to create new classes just for parsing a yml ...)

kotlin only have few functions for concurrency, you'll need to use libraries like quasar, kovenant or lambdaqueues.

Blog Archive