Sunday, June 04, 2017
I can't use alt
key combos in netbeans under os x
found this stack overflow answer useful:
download this keyboard layout for us english
copy it to ~/Library/Keyboard\ Layouts/
go keyboard system preference panel, under input sources tab, click +
to add the layout.
however, alt
key combos fires they key twice, so still useless.
zpresent.el is an emacs package for presentation
just create an org file and m-x zpresent
will start the presentation.
(setq mode-line-format nil)
to hide mode line
to do it globally, use (setq-default mode-line-format nil)
I like erlang/elixir's pattern matching (comes from prolog, but prolog is two-way unification)
I want to use them more when I do clojure, I'm ready to use core.match and defun heavily.
also studying clara-rules: Forward-chaining rules in Clojure.
reading Reactive Programming with RxJava, slowly.
rx
started at microsoft, then those people went to netflix, facebook etc. rxjava
was created by netflix.
the core of rxjava
is Observable
, and Observable
is about pushing.
in contrast to Iterable
(pulls)
I like the explaination they gave on performance of nginx vs tomcat:
event loop has performance advantage because hot threads, tomcat starts new thread on new request, which is cold and of course it takes time to warm up.
Friday, June 16, 2017
SREcon17 Asia/Australia has some pretty good topics.
I watched InnoDB to MyRocks Migration in Main MySQL Database at Facebook, learned more about MySQL internals.
I want to try MyRocks simply because it saves more space than compressed InnoDB, which is the biggest pain point on a $5 digitalocean droplet.
this guide teaches you how to build it under ubuntu and migrate from innodb to myrocks
further reading: MyRocks: A space- and write-optimized MySQL database
reading Understanding ECMAScript 6: The Definitive Guide for JavaScript Developers, quite good.
I finally understand yield
after reading this book:
yield
stops the function right after it's being called, so this code
let a = yield 1;
the assignment will be executed on the next yield
, but you can call the next yield
with next(5)
, so when the assignment happens, a
will be 5
anyways, es6 is very different from the javascript I'd learned before (I read quite a few javascript books). but it's better, like kotlin to java.
I watched Anthony Marcar - Clojure At Scale @WalmartLabs, he mentioned component helps them to scale.
then I watched Stuart Sierra - Components Just Enough Structure
so in clojure, there're few libraries to help you maintain states:
- stuartsierra/component: Managed lifecycle of stateful objects in Clojure
- tolitius/mount: managing Clojure and ClojureScript app state since (reset)
- danielsz/system: Reloaded components à la carte
- weavejester/integrant: Micro-framework for data-driven architecture
there're tons of discussions on component and mount:
- Contrasting Component and Mount, discussions
- The Beauty of Clojure, discussions
- How I use Component, discussions
- Differences from "Component"
- A Tutorial To Stuart Sierra's Component
- Integrant: an alternative to Component and Mount
I picked mount, I don't mind to use global def
s, I just don't want to pass extra parameters around.
Recently I've been using a lot mount and core.match, finally I can produce some clojure codes which is easy to read and easy to maintain.
read Reducers, transducers and core.async in Clojure, I've been working on some ETL tasks
so I watched Simplifying ETL with Clojure and Datomic - Stuart Halloway
I think core.async and transducers are good fit for etl jobs, I'm working on porting some of tasks to channels
I also found a good resources on core.async: Eric Normand's Core.async Patterns, and codes on lispcast/core-async-patterns.
some good reads:
- Clojure Concurrency: Ultimate GuideSticks and Stones and Sorcery
- Network protocols: For programmers who know at least one programming language
- You Are Not Google
- Why You Can’t Help But Act Your Age
- For an Inclusive Culture, Try Working Less
- Engineering Empathy
Saturday, June 17, 2017
got my vortex core keyboard, it's very nice looking
however, 47 keys are not easy to use. the biggest problem with it is how to make pn
and left space
less wasted.
even with the latest firmware, you can only switch pn
OR fn
, not both.
I tried swapped pn
and fn
, and set left space
as alt
, but didn't work well.
I finally mapped left space
as fn
, and left pn
being wasted.
the final version is like this:
|------------+-------------------+----------|
| new key | current key | output |
|------------+-------------------+----------|
| row 1 | | |
|------------+-------------------+----------|
| fn + esc | fn1 + shift + esc | ~ |
| fn + q | fn1 + shift + tab | ! |
| fn + w | right shift | up |
| fn + e | fn1 + shift + s | # |
| fn + r | fn1 + shift + d | $ |
| fn + y | fn1 + shift + g | ^ |
| fn + u | fn1 + shift + h | & |
| fn + i | fn1 + shift + j | * |
| fn + o | fn1 + shift + k | ( |
| fn + p | fn1 + shift + l | ) |
| fn + del | fn1 + m | [ |
| fn + bs | fn1 + , | ] |
|------------+-------------------+----------|
| row 2 | | |
|------------+-------------------+----------|
| fn + a | right alt | left |
| fn + s | menu | down |
| fn + d | right ctrl | right |
| fn + f | fn1 + shift + f | % |
| fn + j | fn1 + ; | - |
| fn + k | fn1 + n | / |
| fn + l | fn1 + enter | = |
| fn + ; | fn1 + b | ' |
| fn + enter | fn1 + . | \ |
|------------+-------------------+----------|
| row 3 | | |
|------------+-------------------+----------|
| fn + x | fn1 + shift + a | @ |
| fn + c | fn + u | pageup |
| fn + v | fn + o | pagedown |
|------------+-------------------+----------|
| row 4 | | |
|------------+-------------------+----------|
| left space | fn | fn |
|------------+-------------------+----------|
note,
- always use
right shift
/menu
/right alt
/right ctrl
asup/down/left/right
(enabled byleft win + left alt + right space
) - once mapped to
fn + key
, it also mappedshift + fn + key
autometically. fn + t
,fn + g
andfn + b
are for time delays, can not be programmed.
I also setup dedicated layer for numbers and arrows.
Wednesday, June 21, 2017
reading MongoDB in Action, Second Edition
there're lots of bad comments on mongodb, however, after read two parts of this book, I found mongodb is a really powerful tool.
I can also see they've been improved quite a lot in recent verisons.
there're few ways to do authentication for aws api gateway calls mentioned in their documentation
however, actually only two are useful for client side javascript:
if you're willing to do a registration flow on cognito, it's the best way. cognito issues token and verify it for you.
otherwise, you'll need to use a lambda to verify tokens issued by your backend or something like auth0 (auth0 can verify tokens for you as well)
some notes from implementing the lambda:
- don't use
Authorization
header (which is default value for a auth lambda), seems it conflicts with aws connections, just use a custom one likeAuth
to save yourself some trouble. curl
is not working. api gateway requires https client supports sni, looks like mycurl
doesn't support it.- they have specific input and output format
also, for lambda using proxy integration, you also need to follow their output format
about aws lambda to connect database, connection pool is a problem, because there's no connection pool.
lambda should be stateless, it can die and restart anytime. so connection pool doesn't make sense to it.
the best way is use a rest api wrapper, but usually it will be difficult to find library to do connection this way.
mongodb article uses a cached connection declared outside of handler function.
which is the way I've been using now: use atom
to hold the connection state.
I think for aws dynamodb they're using rest api endpoints. so no this problem.
about dynamodb, some notes too:
- it supports conditional upsert, which is nice
- supports secondary index keys
- basicially you'll need to involve the primary key all the time, key-value storage ...
- no aggregation, if you need it, dynamodb probably not for you.
the query is quite limited and it requires more effort on application side.
for me, serverless is still quite painful to work with: too many small pieces, hard to test, it scales well (means you don't want it connecting to your existing infrastrucure/applications, unless your application scales that well too)
Saturday, June 24, 2017
I'm wondering why dynamodb only said they're doing partitioning, instead of sharding.
I did some search, partitioning is a more generic term, horizontal partitioning is one of partitioning type, and sharding is basically horizontal partitioning except:
Horizontal partitioning can be done both within a single server and across multiple servers, the latter often being referred to as sharding.
still didn't get the answer, dynamodb obviously is sharding, but why only term partitioning is used?
I'm looking for a better way to handle exceptions in clojure, I found MichaelDrogalis/dire: Erlang-style supervisor error handling for Clojure useful.
let's take a look at its self correcting example:
(ns mytask
(:require [dire.core :refer [with-handler supervise]]
[fs.core :refer [touch]]))
(defn read-file [file-name]
(slurp file-name))
(with-handler #'read-file
java.io.FileNotFoundException
(fn [exception file-name & _]
(touch file-name)
(supervise #'read-file file-name)))
(supervise #'read-file "my-file")
which is super nice.
Sunday, June 25, 2017
I usually don't write tests, but Midje is what I will use if I have to.
just add this to project.clj
:
:profiles {:dev {:dependencies [[midje "1.8.3"]]}}
test files locates:
├── src
│ └── quux
│ └── core.clj
└── test
└── quux
└── core_test.clj
a simple test is like:
(ns myproject.core-test
(:require [midje.sweet :refer :all]
[clojure.string :as str]))
(fact "simple test"
(str/split "a/b/c" #"/") => ["a" "b" "c"])
you can run tests in cider
repl too:
user> (use 'midje.repl)
user> (load-facts) ;; load all facts
user> (check-facts) ;; recheck facts
user> (autotest) ;; watch file changes and load facts
user> (autotest :stop) ;; stop autotest, also has :pause, :resume
to run test from lein
, add lein-midje
to your ~/.lein/profiles.clj
first:
{:user {:plugins [[lein-midje "3.2.1"]]}}
then you can run
$ lein midje // load facts
$ lein midje :autotest // watch file changes and load facts
I have to say the autotest
feature is very useful.
to exclude all clj/cljs/cljx
files in a uberjar
, add this line to project.clj
:
:uberjar-exclusions [#"\.(clj[x|s]?|java)"]
Tuesday, June 27, 2017
reading an old book: Clojure High Performance Programming
learned a thing I didn't know before:
locking, same as synchronized
in java
pretty low level but good to know.
I did few aws lambda in clojure, but the team wants node.js, so I have to rewrite it.
very unhappy with that, IMHO clojure version is more concise and solid, node.js one is ... meh.
but I have to admit node.js is more suitable for aws lambda, you don't even need to include the aws sdk, just a js file.
I felt a little bit better after listening defn episode #23 - Stuart Halloway
clojure is definitely not dying, because there are still very great developers working on it.
I really should dive into spec and datomic, they're good thinkings and make clojure unique.
category theory, I still don't get it
but for clojure here's a library: funcool/cats
I want to try their Maybe
, Either
and Exception
types, mainly for error handling.
while working with node.js, I use vim
I set these two options:
set makeprg=node\ %
set autowrite
then run the script with :make
, it should work for ruby
, php
etc.
put this to .vimrc
to enable it by file extensions:
autocmd BufNewFile,BufRead *.rb set makeprg=ruby\ %
autocmd BufNewFile,BufRead *.pl set makeprg=perl\ %
autocmd BufNewFile,BufRead *.php set makeprg=php\ %
autocmd BufNewFile,BufRead *.js set makeprg=node\ %
autocmd BufNewFile,BufRead *.sh set makeprg=bash\ %
Thursday, June 29, 2017
when using custom authorizer for api gateway, if you want to get the user id embed in the jwt, you can set the principalId to contain the user id, the lambda callback function should be able to get it via event.requestContext.authorizer.principalId
I put my reading notes for two books I read recently:
Blog Archive
- Newer Entries
- 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
- 2024 December
- Older Entries
- 2017 May
- 2017 April
- 2017 March
- 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