My Desktop With i3, polybar, conky, and rofi
This weekend i’ve been playing with my i3 desktop settings. Here are the result
Made with:
- Window Manager: i3
- Background: Ori
- Color Scheme: Nord
- Polybar: adi1090x/polybar-themes-8
- Conky: conky
This weekend i’ve been playing with my i3 desktop settings. Here are the result
Made with:
If you are in the need of converting your custom intellij live tempate, you can use this method to transform it.
The first thing you need to is is to locate the template file. You can find it inside the intellij settings directory which is vary per operating system. See this documentation to locate it.
For example for my golang templte in linux, I find it under
/home/username/.config/JetBrains/IntelliJIdea2020.1/jba_config/templates/Golang.xml
You can use tihs gocode
|
|
Copy the output of the file. On vscode, Ctrl+p
to bring the command and search for Configure User Snippet
. Chose the language and then paste it.
It’s all started when my colleague asked this question.
|
|
Which one do you think is faster?
$ go test -bench .
goos: linux
goarch: amd64
BenchmarkForVar-4 4363 269711 ns/op 0 B/op 0 allocs/op
BenchmarkForCounter-4 4195 285952 ns/op 0 B/op 0 allocs/op
PASS
ok _/test1 2.685s
It’s pretty much the same. However, if we increase the size of the struct by adding another field ID9 int64
The result becomes significantly different.
$ go test -bench .
goos: linux
goarch: amd64
BenchmarkForVar-4 282 4264872 ns/op 0 B/op 0 allocs/op
BenchmarkForCounter-4 4363 269761 ns/op 0 B/op 0 allocs/op
PASS
ok _/test1 3.255s
This problem become intriguing, so I dig a little deeper. I would like to point out that the code is a contrived example.
It would probably not applied in a production code. I am not going to focus on the benchmark or which for-range works
better but rather exploring how Go compiles and demonstrating useful Go tools in the process.
The code below also contains some assembly code. I am not going into too much detail, so I would not worry if you are not familiar with it. My intention is to show how the generated code differs and what could be the reason for it.
I am going to focus on for _, s = range slice
loop (ForVar). To make it simpler I create a main.go
and struct.go
main.go
|
|
I’ll skip the struct.go
here since it’s pretty trivial.
To look into what instructions are generated, we can use go tool compile -S
. This will print out the generated
assembly code to stdout. I also Skipped some lines that are not directly related to our code.
according to asm package doc
The FUNCDATA and PCDATA directives contain information for use by the garbage collector; they are introduced by the compiler.
|
|
Here are the generated assembly code for both version.
version with 9 int64
This struct contains 9 int64 and has the size 72 bytes
|
|
Here you can see that at line 00065
, the loop does nothing except increasing the counter. Let’s compare it with the
larger struct.
The struct now contains 10 int64 and has the size 80 bytes
|
|
The conclusion is that with 80 bytes struct, every iteration copies the value of the element.
To understand how this code is generated, we first need to understand how GO compile a source code.
Stream wrote a very good introduction to the topic on
How a Go Program Compiles down to Machine Code.
The short version is the compiler does:
|
|
Each column represents the optimization pass, and the result of the IR code. When we click on a block, variable, or line. It will colorize the associated element, so we can track changes easily.
![Generated SSA HTML](forVar_small_ssa.png)After comparing each step, I found out that the generated code was identical until the writebarrier
pass.
let’s focus on block b6
writebarrier
(identical on both versions)
b6: ← b3 b4
v22 (7) = Phi <*SomeStruct> v14 v45
v28 (7) = Phi <int> v16 v37
v23 (7) = Phi <mem> v12 v27
v37 (+7) = Add64 <int> v28 v36
v39 (7) = Less64 <bool> v37 v8
v25 (7) = VarDef <mem> {.autotmp_7} v23
v26 (7) = LocalAddr <*SomeStruct> {.autotmp_7} v2 v25
v27 (+7) = Move <mem> {SomeStruct} [72] v26 v22 v25
If you see on v26 & v27
, it does Move
(or Copy) the content of the struct to local variable autotmp_7
.
The lower
pass basically convert the IR code into specific architecture low level code. Let’s have a look at the generated output.
Don’t be afraid if you don’t really understand the assembly. What I wanted to show is the different code that was generated during
the lower
pass.
lower
with 9 int64
b6: ← b3 b4
v22 (7) = Phi <*SomeStruct> v14 v45
v28 (7) = Phi <int> v16 v37
v23 (7) = Phi <mem> v12 v27
v37 (+7) = ADDQconst <int> [1] v28
v25 (7) = VarDef <mem> {.autotmp_7} v23
v26 (7) = LEAQ <*SomeStruct> {.autotmp_7} v2
v44 (7) = CMPQconst <flags> [1000000] v37
v32 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [8] v2
v31 (+7) = ADDQconst <*SomeStruct> [8] v22
v29 (+7) = MOVQload <uint64> v22 v25
v24 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [40] v2
v15 (+7) = ADDQconst <*SomeStruct> [40] v22
v46 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [56] v2
v35 (+7) = ADDQconst <*SomeStruct> [56] v22
v21 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [24] v2
v17 (+7) = ADDQconst <*SomeStruct> [24] v22
v39 (7) = SETL <bool> v44
v42 (7) = TESTB <flags> v39 v39
v30 (+7) = MOVQstore <mem> {.autotmp_7} v2 v29 v25 # <-- start translated Move instruction
v41 (+7) = MOVOload <int128> [8] v22 v30
v20 (+7) = MOVOstore <mem> {.autotmp_7} [8] v2 v41 v30
v34 (+7) = MOVOload <int128> [24] v22 v20
v19 (+7) = MOVOstore <mem> {.autotmp_7} [24] v2 v34 v20
v33 (+7) = MOVOload <int128> [40] v22 v19
v38 (+7) = MOVOstore <mem> {.autotmp_7} [40] v2 v33 v19
v47 (+7) = MOVOload <int128> [56] v22 v38
v27 (+7) = MOVOstore <mem> {.autotmp_7} [56] v2 v47 v38
b6: ← b3 b4
v22 (7) = Phi <*SomeStruct> v14 v45
v28 (7) = Phi <int> v16 v37
v23 (7) = Phi <mem> v12 v27
v37 (+7) = ADDQconst <int> [1] v28
v25 (7) = VarDef <mem> {.autotmp_7} v23
v26 (7) = LEAQ <*SomeStruct> {.autotmp_7} v2
v44 (7) = CMPQconst <flags> [1000000] v37
v32 (+7) = LEAQ <*SomeStruct> {.autotmp_7} [8] v2
v31 (+7) = ADDQconst <*SomeStruct> [8] v22
v29 (+7) = MOVQload <uint64> v22 v25
v39 (7) = SETL <bool> v44
v42 (7) = TESTB <flags> v39 v39
v30 (+7) = MOVQstore <mem> {.autotmp_7} v2 v29 v25 # <-- start translated Move instruction
v27 (+7) = DUFFCOPY <mem> [826] v32 v31 v30
LT v44 → b4 b2 (likely) (7)
The later version uses DUFFCOPY
to perform the Move operation. This logic I believe is due to a rewrite rule
rewriteAMD64.go. It’s an optimization
to Move a large byte on memory.
// match: (Move [s] dst src mem)
// cond: s > 64 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice
// result: (DUFFCOPY [14*(64-s/16)] dst src mem)
At a later SSA pass (elim unread autos
) the compiler can detect that there are unused temporary
variable for the first version (9 int64 struct). Thus, the Move
instruction can be removed.
This is not the case with for the `DUFFCOPY' version.
That’s why the generated machine code is less optimized than the previous.
Note: A Duff Device is a loop optimization by splitting the task and reduce the number of loop.
for-range
behaves differently depending on the struct size is due to Compiler SSA optimization. The compiler generated
a different machine code for the larger struct where at a later pass it did not detect unused variable. The opposite happen
for the smaller struct. At a later pass, it detected that some variables are un used. It removes the copy of element
instruction on each iteration.
I’m so excited with the new release of golang. One particular feature is now very easy to build for multiple architecture. If you seen my other posts, I also like to tinker with my raspberry-pi. On my previous project I use either ruby or python for building some stuff. One annoying thing is dependency, setup and compilation is usually quite slow. Would be cool if I could just create some stuff in desktop and just scp the binary to pi and everything should work!
There is this nice article that explain the process. Let’s start there and create simple application
|
|
Let’s try to build it
|
|
Now, crossing my finger, and run it on my pi
|
|
Holy crap, it’s that easy. I’m excited. Let’s see if go routine works
|
|
Again, build and scp, and cross some more fingers
|
|
Super awesome indeed, it just works!. Oh and the binary is not that big 1.9M considering it statically include the library.
Hmm let’s try something fun that fiddle with the gpio pin. Let’s create something that what raspberry-pi made for.. blinking led :p
There is already library. Let’s starts there.
|
|
Dayuumm.. It’s that easy. No more pip install or bundle install on pi. Just scp the binary!
Of course we’ve got this far, we must try to control it remotely via HTTP.
|
|
Look at that. All it takes to do that is just 67 lines of code. The main logic just about 31 lines. That’s including the fancy dancing blinking. No framework, only gpio dependency. Everything else is go stdlib.
Ok, let’s do one other thing. The reverse! Trigger something when button is pressed. For this let’s just use websocket, and see how hard it is to implement this. What this mean that if you have websocket client (web browser) you could listen to event and stream it directly from your raspberry-pi to your computer.
|
|
You see there I connect 2 client. One browser and the other one is cli app that I created. Notice that they got their messages alternately between each other. This is because they are sharing the same channel. I will leave it to you my kind reader as an exercise to make it broadcast the message instead of distributing them :)
all source are available at https://github.com/yulrizka/go-pi-experiments
Push To Talk app for OSX
As a part of scrum teams, every day I need to give updates to my team via Google Hangout. We have a team here in the Netherlands and also in Indonesia. Some times I am in the same room as a colleague of mine. This sometimes quite annoying because I can hear my self (with a delay) from his mic. This somehow messed up my brain. Google Hangout already has a ‘auto adjust mic volume’ that is really great which cancel the noise. But we still have a problem and end-up muting each other when we want to talk.
There are currently an App that does this already on Apple store, and pretty cheap too. Nevertheless I could not find the one that is suitable for my needs. And I would like to develop an OSX app since I never done it before. Even though i have a hate-love relationship with XCode, I have to give credits to XCode. It’s quite easy to create an app like this.
The app sits on status-bar (tray icon ?). By default it muted the microphone and show translucent mic icon. If you hold down the Right Options key, it will un-mute the microphone as long as you pressed it. when you release the key, it will mute the microphone until you press the key again or quit the application.
Everything is at github.com/yulrizka/osx-push-to-talk:
I’ve only tested this app on my MacBook running Yosemite.
If you are on Linux, there is also a phython GTK app that does this really nicely.
If you are on windows, well Godspeed my friend :)
veel succes!
I’ve been involved with a iOS project this past week. I’m adding functionalities to the CommonSense iOS library. One of the most annoying thing is that it took about 2 minute to load the project. This is only happened in the unstable branch. The master branch seems to be working fine. So I knew that somewhere there is a commit when this starts happening.
Now this is a good example where git bisect
is very useful. It will perform a binary search through commit history until the first
bad commit found. So you start with a commit and you marked is as a ‘good’ or ‘bad’. Then every time you mark a commit as good / bad,
it will then checkout another commit half way in the middle point between previous history. In each checkout then you test the code and see
whether the bugs exist or not.
Here is an example
|
|
the prompt sense-ios-library
shows the current folder, and git:(unstable)
show current commit. it’s part of oh-my-zsh plugin
|
|
Now that you know when was the bugs introduced. you can now start looking at the problem.
I found out there is something that doesn’t feel right here github:commit/e5c40.
There is a reference to Xcode.app
in one of the folder. So every time I open the project,
or switch branch, it will try to look into things inside Xcode.app
.
So removing the reference indeed solve the problem.
The bisect function is very versatile tool to track down when a bug was introduced. You can even automate the test so you don’t have to check each bisect commit your self. The bisect documentation provide a good explanation about the command and also an example on how to automate the test.
Now go on catch and squash those annoying bug!
Sometimes it’s really hard to test functionality that involve with system time. Especially when we want to test the function with a specific time. For example testing whether today is end of month or test 2 different behavior at a different time
Below we look into different ways we can mock or stub the time. Each with it’s own advantages and disadvantages.
|
|
This way you can either pass time.Now()
in your main pacakge
or call it with something like time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.UTC)
in your test.
Advantages:
Disadvantages:
|
|
Advantages:
CheckEndOfMonth
not at the caller.Disadvantages:
|
|
on the test code
|
|
Advantages:
Disadvantages:
Previous examples require you to pass in either concrete instance or a function on the caller.
Another approach you can use is to create a package level function to generate current time. You can change the implementation during test.
|
|
now in your test you could do something like this:
|
|
Advantages:
Disadvantages:
resetClockImplementation
If you are lucky enough to work in a struct, you can do this
|
|
And the test can be
|
|
I like this method because you don’t have to pass instance of time or function all over the place but still have it easily create an arbitrary time mock/stub
Make this pattern reusable
If you do this more often, you can also easily reuse the functionality into other struct
by creating embeddable
|
|
in test
|
|
Advantages:
TimeMock
by adding more function that is neededDisadvantages:
Function with time is usually hard to test because it dependency with on time package.
A different way to test is to separate the function that generate the time with the function that process the time value. For example
|
|
Instead of testing that function, extract the logic of processing time
|
|
this way you don’t test the CheckEndOfMonth()
but processEndOfMonth
. This way you can easily
mock time without the need to do some wiring.
You are probably familiar with above images. Some random friend sent you an email which you can instantly recognize as a spam because it only contains one link. Couple days ago I receive this email which is not the first time for me. But this time it was different. It actually came from my own Yahoo! account which I never use since more that one year ago.
My first instinct is to check whether the mail really got sent from my account or it just spoofing my email address. I kinda guess already that it is using my main account because the list of recipient is looks like it came out of my address book. So I went to my account and check the sent mail folder and there it is. One email message containing a spam that I actually sent to my friends and family.
Did some digging to my authentication history and found out that somebody from Romania has access my account. How could this be. I’ve never use the account since one or more year ago, I’m an IT guy so I know a little bit about security. I don’t click some random suspicious link. I don’t install any annoying-spyware-browser-toolbar. The password is 12 character long with apla-numeric and random symbol. Thank god that I don’t use the same password for all of my account.
I did again some digging to the given IP address and found out that the IP address came from a location in Rumania. But again this would not be his/her real IP. If i was to send a spam, I will route my email through bunch of proxy all over the world to cover my track. Or probably they don’t even bother because they just using it for spam.
Interesting part is I stumble upon this article saying about Romania has became a Global Hub for hackers and online crooks. According to the article that it’s became a commonplace for some hacker to harness people personal information and use it for illegal activity.
Luckily I don’t store any sensitive information on my email. It would have some serious impact if I store password or bank account information.
Also something that I notice is most of this spam email came from my friends account which also uses Yahoo! mail. Or probably I just never notice.
If you ever received / sent this email. I would suggest you to:
Berksfhel is cookbook dependency for chef. If you are familiar with ruby / python, think of it as a Bundler or virtual environment for chef
I faced this core dump error while doing berks upload
. That command will actualy
push some cookbook to a chef server.
|
|
upgrading the ruby verison to 2.0 seems to resolve my issue.
When working in teams, we are sometimes required to share some password / keys with our team. The most common way for me is probably through email or some chat client. But even though its convenience it’s not actually a secure and a good practice. Especially if you are providing a service that deal with sensitive information.
Some simple approach would we communicating the password directly with a person through secure medium. One way to do it is both party ssh through a server and use talk client like write. But for some cases it’s quite impractical.
Enter PGP. It’s basically a software that do a Public-key cryptography. Public-key cryptography is basically encryption process which require 2 keys, one for encrypting and the other one for decrypting. Usually the public key is used for encrypting and private key is use for decrypting. I would not dive into the details about it since I’ve only have basic understanding about it. But for those people that is interested, you would read the nice article on wikipedia
There is a open source project called GPG (GNU Privacy Guard) and in this article I would like to show you how we could share some password / key file with it.
If you don’t already have it on your system, you could installed it with:
|
|
After installing we would start by creating a pair of keys
|
|
You will be asked with bunch of questions. Most of the answer you could leave it as a default but most important is fill in your email
address and also provide a Passphrase to protect your key with password. When it finish gathering information, it will start
creating a key pair by using system entropy. You can help the system to generate the entropy by clicking or moving your mouse randomly
or doing some random IO disk by triggering for example find /
After installing, you can see list of keys by using this command
|
|
In above output you could see that we have created public key with id of 70280895
. Note this one because we are going to use it later
when submitting the key to a key server
To share your public key, so other people could send you encrypted message.
Note that further in this article I will discus ways to easily distribute your public key.
|
|
With those generated keys, we could now do a personal encryption. That is if you want to encrypt a file and you are the only one who are able to decrypt it.
|
|
Those code will create a file name message.txt.gpg
which is encrypted message of message.txt
|
|
As you can see that we are successfully decrypted the message. This example you encrypt the message using your own public key. So this method only work if you want to archive or backup the file securely. In order to send someone else an encrypted message, you need to encrypt the message using the other person public key
In order for any body to send you a encrypted message, you need to give your public key. Since public key only used for encryption, It’s OK to publicly share your public key. But never share your private key. Once the other party have your public key they could start send you an encrypted message using the command above.
You could share your public key manually to some one (through usb / email etc) by exporting it first just like I mention before. But there are an easy way to distribute the key. There are some public GPG server that store your public key so that other people could easily find it and import it into their local machine. There are http://pgp.mit.edu and also ubuntu key server http://keyserver.ubuntu.com that we can use.
To send our key to MIT server we could do
|
|
the last number 70280895
was the key id of the public file. You could find it with the output of gpg --list-keys
command.
Now we have successfully send our public key any body could get your public key through that keyserver. You could test this
by searching a name or email or a person in the key server web interface. for example try searching my name on http://pgp.mit.edu/
Now to import other people public key, we could also do that in two way.
if the person give you a file which contain their public key (say ahmy-pub.key
). you could import it with
|
|
Or if the person already publish his public key to a keyserver, we can search it with
|
|
It will generate a list of keys that found on the keyserver. Enter the number of the keys and it will be imported to your local machine.
after importing you can send an encrypted message to the person for example
|
|
You could provide a name or an email address as a recipient.
THis command will encrypt the message using public key of a person name Ahmy Yulrizka
At this point you are able to generate, export, distribute and import keys. More over you can already encrypt and decrypt file / message to a designated recipient. The the part two of this article I will share some idea how we could share some password / password key to other member of the team.