Food poisoning in guilin academic conference

23rd to 25th of August 2018, CAD&CG, GDC held in Guilin, Guangxi Provence, China. After the 25th launch, many attendees started headaches, fever, diarrhea, abdominal pain, nausea, and vomiting. In 27th, attendees received an emergency notification, said that authority confirms it’s a Salmonella poisoning. Here is the official report:

A food poisoning occurred at about 7 o ‘clock on August 26, 2018, at the Dihe international hotel in Guilin. As of 18:00 on August 27, a total of 159 people were admitted to the hospital for examination and 92 were hospitalized, with no critical or fatal cases. At present, 20 people remain in the hospital for observation.

official report

Here is a Unofficial information: 600 people attend this conference, include 70 years old professors, some young professors. It also said more than 300 suffer from the toxic symptom. Some old professors started to get poisoning symptoms in return trip and don’t receive promote medical treatment. Even worst, some young teacher received critical condition notice. Some professors have written testament. A female professor, without knowing to be pregnant, was informed that the baby maybe infanted by Salmonella, that means there is a risk of fetal malformation. The doctor suggests abortion. Here is the screenshot of chatting.

The doctor suggests abortion

What’s the hotel’s current situation?

Officially, the hotel was shut down pending further investigation. But, according to some Weibo, the hotel is still opening.

But above is not the worst.

Some people commit on relative Weibo, forum thread:

阅读更多

Shadowsocks + simple-obfs + IPv6 [CentOS 7]

Sometimes, the network traffic need to be encrypted and obfuscated. shadowsocks + simple-obfs is a simple solution.

shadowsocks is a socks5 proxy, with traffic encryption. all traffic through shadosocks will be encrypted.

simple-obfs is used for obfuscate traffic. The upstream traffic encapsulation in HTTP or tls stream. The outer traffic will look like an HTTP session.

Server-side config

Install shadowsocks, simple-obfs

Enable copr and install:

1
2
3
curl https://copr.fedorainfracloud.org/coprs/antonchen/proxy/repo/epel-7/antonchen-proxy-epel-7.repo \
-o /etc/yum.repos.d/antonchen-proxy-epel-7.repo
dnf install shadowsocks-libev simple-obfs

Config shadowsocks:

1
2
3
4
5
6
7
8
9
10
11
12
# cat /etc/shadowsocks-libev/config.json
{
"server": \["\[::1\]", "127.0.0.1"\],
"server\_port": 8888,
"password": "Password",
"timeout": 600,
"method": "salsa20",
"fast\_open": true,
"workers": 2,
"plugin": "obfs-server",
"plugin\_opts": "obfs=http;fast-open=true"
}

server with value ["[::1]", "127.0.0.1"] means listen 127.0.0.1 and ::1(localhost in IPv6), not listen all interface.

阅读更多

扇贝单词的一些缺点

最近一段时间,我成为了扇贝单词的重度用户。过去的60天,我给扇贝提了20条建议。

但,客观来讲扇贝还是有很多缺点,所以记在这儿,供各位参考。

  1. Web和app功能不一致
    1. 比如app有听词模式,web没有
    2. 比如web可以编辑释义,app不能
    3. 比如web可以添加例句,app不能
  2. Web的释义和app释义不一致,官方回复是app是新版,而web正在改版
  3. 释义不准确,比如有的缺少释义、有的没有释义(我很好奇,没有释义的单词是怎么录入的?)
  4. 单词读音展示问题
    1. 有的单词是美音和英音读音不一致,然后我点击美音,它把两个读音都读出来了……
    2. 有的单词是,不同读音对应不同含义,扇贝根本没有标记出来读音和含义的对应关系
  5. 网页背单词,在Firefox上,快捷键没法使用

我当前在背考研单词。等当前词本结束之后,我会尝试下其他背单词软件的。

阅读更多

Firefox不应该管理DNS(和证书库)

Firefox已经越俎代庖,开始管理证书了,而且还想染指DNS。

最近Firefox在nightly版本中添加了DNS overt HTTPS的支持,第一眼就觉得这个事情不是系统来做吗?比如Android支持DNS overt HTTPS才是比较合理的事情嘛。

看了Reddit上面的评论,发现其他人也有类似的感觉,不止一个人觉得这事应该由系统来做。

另外,这也可能会导致hosts文件配置失效;而在web开发中,修改hosts文件是常用的操作。

而且,Firefox中没有清除DNS缓存的地方,所以很多时候,对于hosts的修改,不能立即在Firefox中看到结果。

总而言之,让浏览器(比如Firefox和Chrome)来管理DNS,不是一个好主意。

说到这儿,Firefox之前也做过类似的事情:

Firefox不知道什么时候,开始自己搞了一套独立的证书信任系统,和系统内置的证书系统是独立的(至少在Android上是这样的)。

比如,我要使用charles抓https的包,需要将charles的tls证书倒入到Andorid系统的证书库中,但是回头一看,Firefox还是不认,所以还得自己将证书添加到Firefox的证书库中。

另外一个更加智障的问题是,我在charles抓包结束后,需要删除这个证书,我可以在Android系统的证书库中删除掉。但是对于添加到Firefox中的那一份,我是没有办法删除的,只能卸载并重新安装Firefox

阅读更多

cherry-pick到底应该怎么翻译?

git当中的cherry-pick命令,翻译成中文叫什么名字呢? GitLab给出了答案

// gitlab.po
msgid “ChangeTypeAction|Cherry-pick”
msgstr “优选”

这个是不是听起来怪怪的? cherry-pick的中文意思是“择优挑选”,比如

They seem to cherry-pick the loss leaders and discount items in the supermarkets and discount stores, relying on smaller retailers for everything else. 因为他们会选择超市和打折店里的特价商品和和打折商品,而其他所有的东西都是从小商贩那里获得。

当然,也要注意的是,写作论文的时候,只挑选那些好的数据写在文章中,这种行为也可以叫cherry-pick,比如:

Be careful not to ‘cherry-pick‘ data: don’t choose just what you like, or what supports your objective. 注意别“优选”数据:别选择一些只是您喜欢的,或者支持您的目标的。

所以从常用语义上来讲,优选这个翻译也不算太差。 但由于“优选”这个词在中国被用烂了,多用在电商等领域,如果我们开发的时候来一句“请将aaa提交优选到B分支”,完全不能理解啊。 个人觉得,翻译成“拾取”会比较好,比如“请将aaa提交拾取到B分支”就顺口好多。


另外,也可以看看GitLab对其他git术语的翻译: Revert 还原,Issue 议题等。

阅读更多

PHP/Composer是如何加载一个类的

PHP/composer开发中,我们只需要require 'vendor/autoload.php',然后就可以直接使用各种类了。那么这些类是如何加载的呢?其中有没有什么可以优化的点呢?

概览

PHP/composer下,类的加载主要到如下部分(还没有包括各个部分的初始化逻辑):

1
2
3
4
5
6
7
8
PHP中zend_lookup_class_ex
|-> EG(class_table)
|-> spl_autoload_call
|-> ComposerAutoloadClassLoader::loadClass
|-> findFile
|-> class map lookup
|-> PSR-4 lookup
|-> PSR-0 lookup

PHP的类加载

首先,PHP在运行的时候,需要一个类,是通过zend_lookup_class_ex来找到这个类的相关信息的。

zend_lookup_class_ex查找类的主要逻辑如下(假设类名字放到变量lc_name中):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload) /* {{{ */
{
// 1. 类名字转化为小写
if (ZSTR_VAL(name)[0] == '') {
lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
} else {
lc_name = zend_string_tolower(name);
}

// 2. 直接在class_table中查找
ce = zend_hash_find_ptr(EG(class_table), lc_name);
if (ce) {
if (!key) {
zend_string_release(lc_name);
}
return ce;
}
// 3. 如果没有autoload_func,则注册默认的__autoload
if (!EG(autoload_func)) {
zend_function *func = zend_hash_str_find_ptr(EG(function_table), ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1);
if (func) {
EG(autoload_func) = func;
} else {
if (!key) {
zend_string_release(lc_name);
}
return NULL;
}

}

// 4. 加载ACLASS的过程中,又加载ACLASS,递归加载,直接找不到类
if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) {
if (!key) {
zend_string_release(lc_name);
}
return NULL;
}

// 5. 调用autoload_func
ZVAL_STR_COPY(&fcall_info.function_name, EG(autoload_func)->common.function_name);
fcall_info.symbol_table = NULL;

zend_exception_save();
if ((zend_call_function(&fcall_info, &fcall_cache) == SUCCESS) && !EG(exception)) {
ce = zend_hash_find_ptr(EG(class_table), lc_name);
}
zend_exception_restore();

if (!key) {
zend_string_release(lc_name);
}
return ce;
}
  1. lc_name转化成小写(这说明PHP中类名字不区分大小写)
  2. 然后在EG(class_table)找,如果找到,直接返回(我们自己注册的类,扩展注册的类都是这样找到的)
  3. 然后查看EG(autoload_func),如果没有则将__autoload注册上(值得注意的是,如果注册了EG(autoload_func),则不会走__autoload)
  4. 通过EG(in_autoload)判断是否递归加载了(EG(in_autoload)是一个栈,记载了那些类正在被autoload加载)
  5. 然后调用EG(autoload_func),并返回类信息

SPL扩展注册

阅读更多

Docker for Mac with Kubernetes初次尝试

首先,2018-01-09日Docker公司宣布了Docker for Mac支持Kubernetes。 后来陆续尝试了几次,今天终于成功了,所以记录下。

安装Docker for Mac with Kubernetes

首先,安装Docker for Mac Edge版本:

brew cask install docker-edge

设置代理(我用的是https://github.com/netheril96/MEOW): 开启Kubernetes:   等待安装: OK了: kubectl version也能看到客户端版本和服务端版本了:

$ kubectl version
Client Version: version.Info{Major:”1”, Minor:”9”, GitVersion:”v1.9.2”, GitCommit:”5fa2db2bd46ac79e5e00a4e6ed24191080aa463b”, GitTreeState:”clean”, BuildDate:”2018-01-18T10:09:24Z”, GoVersion:”go1.9.2”, Compiler:”gc”, Platform:”darwin/amd64”}
Server Version: version.Info{Major:”1”, Minor:”9”, GitVersion:”v1.9.2”, GitCommit:”5fa2db2bd46ac79e5e00a4e6ed24191080aa463b”, GitTreeState:”clean”, BuildDate:”2018-01-18T09:42:01Z”, GoVersion:”go1.9.2”, Compiler:”gc”, Platform:”linux/amd64”}

创建kubernetes-dashboard 服务

$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
secret “kubernetes-dashboard-certs” created
serviceaccount “kubernetes-dashboard” created
role “kubernetes-dashboard-minimal” created
rolebinding “kubernetes-dashboard-minimal” created
deployment “kubernetes-dashboard” created
service “kubernetes-dashboard” created

等一会就可以看到创建好了:

$ kubectl get pods –namespace kube-system
NAME READY STATUS RESTARTS AGE
etcd-docker-for-desktop 1/1 Running 0 6m
kube-apiserver-docker-for-desktop 1/1 Running 2 6m
kube-controller-manager-docker-for-desktop 1/1 Running 0 6m
kube-dns-6f4fd4bdf-zl9dh 3/3 Running 0 7m
kube-proxy-xsx8n 1/1 Running 0 7m
kube-scheduler-docker-for-desktop 1/1 Running 0 5m
kubernetes-dashboard-5bd6f767c7-6szsl 1/1 Running 0 1m
$ kubectl get deployments –namespace kube-system
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kube-dns 1 1 1 1 7m
kubernetes-dashboard 1 1 1 1 1m

阅读更多

如何在macOS上运行GTK 3(hello, world)

首先,安装 Homebrew

然后,brew install gtk+3 随后,查阅GTK的官方文档,写Hello, world:

hello.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <gtk/gtk.h>

static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;

window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
}

int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;

app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);

return status;
}

然后编译:

1
gcc `pkg-config --cflags gtk+-3.0` -o hello hello.c `pkg-config --libs gtk+-3.0`

当前目录下就有了hello二进制可执行文件,执行即可:

阅读更多

Use pty as ansible connection

Well, sometimes, we can only use pty to access machines. For example, Jump Server only allowed use ssh pty to type command, get the result. But, how can I deploy application via ansible?


There are two good news:

  1. pexpect can interactive with the ssh session.
  2. ansible can use custom connection plugin.

Let’s try it

Let’s start at directory ansible-pty Firstly, we should create a connection plugin. Put those code to ansible-pty/plugins/pty.:

import base64
import re

import pexpect
from ansible.plugins.connection import ConnectionBase
from ansible.utils.display import Display

display = Display()

class Connection(ConnectionBase):
transport = ‘pty’
_mark = “=” * 10

阅读更多

[评论]systemd @ Facebook — a year later[All Systems Go! 2017]

今天看了All Systems Go! 2017上,systemd @ Facebook — a year later这个talk。记录下自己的感想。

首先,Facebook软件更新还是比较及时的,CentOS 7 和 systemd 都上了:

可怜我司还在Ubuntu 14.04上 另外,很多基础组件都是和上游有良好的沟通的:

长远来看,紧跟上游对公司的技术实力、技术影响力都有好处。当然,短期来看,我的系统工作的很好,不跟进上游没毛病啊。国内,大部分是后者吧……

当然,大公司都有自己的repo:

Facebook居然都已经接入了Meson,很让我吃惊。

资源管理

阅读更多