Nhảy tới nội dung

· Một phút để đọc
Huy-Tu Nguyen

Chắc hẳn ai cũng muốn (không muốn thì đến lúc cũng phải muốn) cái app mình code chạy nhanh nhất, responsive nhất nên không lạ gì với các thông số đo đạc performance của hệ thống để biết nó nhanh hay chậm. Vài cái tiêu biểu là latency & throughput.

[Concurrency series] #1 Đo đạc tốc độ

Latency (độ trễ) là thời gian từ khi gói tin được gửi đi cho đến khi gói tin được nhận, hay là thời gian từ khi bắt đầu tới khi hoàn thành task, hay là. Latency cao nghĩa là độ trễ cao, aka thời gian hoàn thành lớn-chậm.

Throughput (thông lượng) là số byte gửi/nhận trong 1 giây của mạng, là số lượng task mà system có thể handle trong 1 khoảng thời gian. Nó thể hiện cho “năng suất”.

Một ví dụ đơn giản là xe máy & xe bus, xe máy có thể nhanh gấp đôi xe bus nhưng xe bus lại chở được số lượng x25 lần xe máy. Xe bus có throughput lớn hơn xe máy.

**

Vậy là hệ thống throughput cao thì latency thấp? Cũng không hẳn như vậy:

Xe máy chở đc 1 người/h, xe bus thì chở 50 người/2h (là 25 người/h). Trong trường hợp này, xe bus có throughput cao, nhưng latency nó cũng cao hơn xe máy. In the end, nó vẫn phải tốn 2h để hoàn thành nhiệm vụ

→ Tương tự trong hệ thống máy tính, không phải throughput cao là đồng nghĩa với latency thấp.

Có 2 điều cần lưu ý rằng:

  • Cải thiện yếu tố này có thể làm tệ đi yếu tố còn lại.
  • Các khái niệm trái nghĩa nhau không đồng thời triệt tiêu nhau mà có thể tồn tại cùng nhau (cái này nói sau hehe).

Nói một cách technical hơn 1 long-running task có thể được chia nhỏ thành nhiều task có thể được thực thi song song, giúp giảm thời gian thực thi → giảm latency. Nhiều task được thực hiện đồng thời cũng là giúp tăng throughput.

x còn giúp che giấu latency.

Một ví dụ đời thực là khi chờ xe bus, thay vì chỉ ngồi chờ, chúng ta có thể làm những task khác như đọc sách, check mail, tin nhắn, gọi điện, ăn sáng, etc.

Đây là những hành động vô thức mà ta làm thường ngày. Tại sao chúng ta làm? → Bởi vì chúng ta “thấy” nó optimize hoạt động của mình.

Tại sao nó optimize? Việc chúng check mail trong lúc chờ xe bus không giúp xe bus đi nhanh hơn?

→ Well thực tế bởi vì chúng ta đã che giấu đi độ trễ của xe bus, i.e. làm task khác trong thời gian đợi task có latency cao. Đây cũng là một ví dụ cho thấy che giấu latency là một trong những key cho 1 responsive system (và đây là đáp án đầu tiên cho bài toán liên quan tới việc waiting).

** Chatchit

Q: Wait, what is x?

A: Based on the title and the bold words, you’ve already known. It is concurrency.

Q: Vậy nói 1 hồi thì liên quan gì tới measurement?

A: Vì nó là động lực. Concurrency không mới nhưng nó là skill cần thiết với modern systems ngày nay.

Q: What is concurrency?

A: Dunno yet.


ResRef: Kirill Bobrov, Manning Publications - Grokking Concurrency

· Một phút để đọc

· Một phút để đọc
Huy-Tu Nguyen

ABC: https://medium.com/always-be-coding/abc-always-be-coding-d5f8051afce2

Broken windows: https://en.wikipedia.org/wiki/Broken_windows_theory

Tách hàm như thế nào

    src = if imageDownloadUrl != null then builtins.fetchurl {
} else fetchEcr {
};

https://en.wikipedia.org/wiki/Duck_typing

Nếu có thể cho rằng bất cứ thứ gì biết bơi đều là vịt vì vịt có thể bơi thì cá voi có thể được coi là vịt; tuy nhiên, nếu người ta cũng cho rằng con vịt phải có khả năng bay thì con cá voi sẽ không được coi là con vịt.

So it seems weird that the function has to be executed either with args A, B or with arg C, D, but no overlap. It doesn't even attempt to catch odd case if all args are specified.

This should be separated back into two separate unrelated functions for clarity, and shouldn't be doEverything(args, for, all, possible, cases)

I don't know if I'd agree with that. It's fine to have two functions returning the same "type" (i.e. in nix's case, similar to JavaScripts, using duck typing). But having function distinctly doing different things just so that it returns same return type is weird. If one function fails to return, for example, imageTag and that key is needed for evaluation, nix evaluation will fail with error message. And if it's not needed, no harm if function doesn't return it.

I.e. there are many functions in nix (that can be used) for fetching git source code: fetchUrl, fetchGit, fetchGitHub, fetchGitLab, fetchTarball, fetchBitbucket, fetchgitLocal , fetchgitPrivate, and possibly even more. There even other functions for svn, hg, and other source-related fetches. Each, in the end, returns one same thing, a git repo. But you'll notice that there is not a function fetchRepo(name, revision, url, git, github, gitlab, tarball, bitbucket, local, private) which would reuse first two args, and then require exclusive 3rd arg (or some combination of exclusive arg sets, such as sometimes asking for authentication or w/e else). Because such a function would be unmanageable and confusing. So I think it's best to separate the two, and, in addition, make it clearer which one is fetching from where and requires what data explicitly (e.g. Ecr fetch always would require aws creds, not optionally)

· Một phút để đọc
Huy-Tu Nguyen

Tâm sự nhảm (skip for now): Năm mới sắp hết, hôm nay là ngày làm việc cuối cùng của năm - friday 29/12 (thật ra hôm nay booked off rồi :v). Nên cũng muốn viết một cái gì đó. Cho nên hôm nay sẽ viết về một thứ liên quan tới công việc của mình trong nửa cuối năm vừa qua, đó chính là làm việc với scripts.

Kinh nghiệm với

Chúng ta luôn có folder dự phòng /tmp ở đâu đó.

Khi làm một lệnh gì đó nên check nếu lệnh đó có thể fail và gây crash. Một số ví dụ

# Copy file ở SOURCE -> TARGET
scp $SOURCE/my_awesome_file $TARGET:/still_my_awesome_file

Nên:

scp ... || (echo "failed yada yada"; exit 1)

Những lệnh cd về technically vẫn có thể failed với những unexpected path.

Use "|| true" to avoid interruption on stopping failure

docker-compose -f ${hostConfig.dockerComposeYmlPath} down -v || true

This stop on errors but hide all errors.

  1. Error
mkdir -p ${hostConfig.dockerRootDataDir} || true
echo "Success!"

$\leftarrow$|| true here seems pointless, as it'll continue anyway. Also confusing in that it'll always write Success! even if mkdir fails -> It was meant to be || exit 1

if [ ! -f "$file_path" ]; then
echo "Expecting the file at path $file_path but it's unavailable. Stop now"

should be going to stderr via >&2?

# For debug when needed
set -x