C0reFast记事本

to inspire confidence in somebody.

Python中的上下文管理器可以允许精确地分配和释放资源,最常用的就是使用with语句,比如:

with open('/tmp/file_x', 'w') as file_x:
    file_x.write('Hello')

with结束,文件也会被安全的关闭。不用担心回收资源的问题了。

如果一个自定义的类也想支持类似的调用方式,需要实现__enter__(self)__exit__(self, type, value, traceback)这两个方法,具体的:

class File(object):
    def __init__(self, file_name, method):
        self.file_obj = open(file_name, method)
    def __enter__(self):
        return self.file_obj
    def __exit__(self, type, value, traceback):
        self.file_obj.close()

其中__enter__方法将打开的文件返回给with语句。
对于__exit__(self, type, value, traceback)方法,会在with语句退出时调用,如果在执行中发现异常,则异常的type,value和traceback会被传递给__exit__方法,在__exit__中可以对异常进行相应的处理,如果最终
__exit__方法返回None,则认为异常被正确处理了,如果返回的不是None,则这个异常会被with抛出,期待上层进行相应的处理。

除了上面的方法,Python还提供了一个contextlib模块,通过这个模块加上装饰器(decorators)和生成器(generators),也能实现类似的功能:

from contextlib import contextmanager

@contextmanager
def open_file(name):
    f = open(name, 'w')
    yield f
    f.close()

这样在使用中,open_file变成了一个生成器,所以contextmanager可以通过调用这个生成器next()方法控制资源的释放,具体的源代码在这里:

# 代码有所省略,具体可以参考: https://github.com/python/cpython/blob/master/Lib/contextlib.py
class _GeneratorContextManager(_GeneratorContextManagerBase,
                               AbstractContextManager,
                               ContextDecorator):
    """Helper for @contextmanager decorator."""

    def _recreate_cm(self):
        return self.__class__(self.func, self.args, self.kwds)

    def __enter__(self):
        try:
            return next(self.gen)
        except StopIteration:
            raise RuntimeError("generator didn't yield") from None

    def __exit__(self, type, value, traceback):
        if type is None:
            try:
                next(self.gen)
            except StopIteration:
                return False
            else:
                raise RuntimeError("generator didn't stop")
        else:
            if value is None:
                value = type()
            try:
                self.gen.throw(type, value, traceback)
            except StopIteration as exc:
                return exc is not value
            except RuntimeError as exc:
                if exc is value:
                    return False
                if type is StopIteration and exc.__cause__ is value:
                    return False
                raise
            except:
                if sys.exc_info()[1] is value:
                    return False
                raise
            raise RuntimeError("generator didn't stop after throw()")

def contextmanager(func):
    @wraps(func)
    def helper(*args, **kwds):
        return _GeneratorContextManager(func, args, kwds)
    return helper

参考:

  1. http://book.pythontips.com/en/latest/context_managers.html
  2. https://github.com/python/cpython/blob/master/Lib/contextlib.py

找到一个命令行版本的speedtest.net,可以在没有浏览器的情况下进行网络测速,具体的地址在[sivel/speedtest-cli][1]
[1]: https://github.com/sivel/speedtest-cli

单文件,只依赖Python,可以直接下载:

curl -Lo speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py
chmod +x speedtest-cli

下载后直接运行即可:

[root@test ~]# ./speedtest-cli
Retrieving speedtest.net configuration...
Testing from XXX Networks (x.x.x.x)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Atlantic Metro (Los Angeles, CA) [1.30 km]: 1.565 ms
Testing download speed................................................................................
Download: 631.41 Mbit/s
Testing upload speed....................................................................................................
Upload: 48.73 Mbit/s

OpenStack Swift中,object replicator的作用是在系统遇到诸如临时的网络中断或磁盘故障后使系统处于一致状态。object replicator会将本地数据与每个远程副本进行比较,以确保它们都包含最新版本。下面会简单分析一下object replicator的代码,了解一下整个Replication的工作流程。

阅读全文 »

在我们内部的系统中,有一个tcp的代理服务,用户所有的网络相关的请求,比如访问外网,或者访问在内网的某些服务,都需要通过这个服务,一方面是实现对外网访问的计费,另外也通过白名单机制,对应用的内网访问进行相应的限制。
随着业务量的增加,发现提供服务的机器负载逐渐变高,当流量高峰的时候,经常出现客户端无法连接的情况,本来这个服务也是一个无状态的服务,可以很方便的水平扩容,在添加机器的同时,也尝试去分析一下程序本身的瓶颈,看能否提升一下程序本身的处理能力,通过分析和优化,还是在一定程度上提升了处理能力

阅读全文 »

在Linux Kernel 4.3中,引入了一个新的cgroups子系统pids,通过这个子系统,可以实现对某个控制组中进程和线程的总数进行限制。
使用前,首先需要挂载该子系统(对于很多的发行版,默认是会挂载的):

[root@test ~]# mkdir -p /sys/fs/cgroup/pids
[root@test ~]# mount -t cgroup -o pids none /sys/fs/cgroup/pids

首先创建一个新的控制组test_max_proc:

[root@test ~]# mkdir /sys/fs/cgroup/pids/test_max_proc
[root@test ~]# ls -l /sys/fs/cgroup/pids/test_max_proc/
total 0
-rw-r--r-- 1 root root 0 Apr 26 09:11 cgroup.clone_children
-rw-r--r-- 1 root root 0 Apr 26 09:11 cgroup.procs
-rw-r--r-- 1 root root 0 Apr 26 09:11 notify_on_release
-r--r--r-- 1 root root 0 Apr 26 09:11 pids.current
-r--r--r-- 1 root root 0 Apr 26 09:11 pids.events
-rw-r--r-- 1 root root 0 Apr 26 09:11 pids.max
-rw-r--r-- 1 root root 0 Apr 26 09:11 tasks

其中,pids.max控制该组中最多可以拥有的进程数,其中线程也包含在其中。pids.current存储了当前控制组的进程(线程)总数。cgroup.procs是需要限制的进程pid。

[root@test ~]# echo 2 > /sys/fs/cgroup/pids/test_max_proc/pids.max
[root@test ~]# echo $$ > /sys/fs/cgroup/pids/test_max_proc/cgroup.procs
[root@test ~]# cat /sys/fs/cgroup/pids/parent/pids.current
2
[root@test ~]# /bin/echo "Here's some processes for you." | cat
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable

可以看到限制生效了。由于Linux的线程也是类似进程的实现,因此,当程序有多个线程时,进程和线程的总数也不能超过设定的值

参考:

  1. http://man7.org/linux/man-pages/man7/cgroups.7.html
  2. https://www.kernel.org/doc/Documentation/cgroup-v1/pids.txt

本篇是Building a Consistent Hashing Ring的翻译,原文一步步描述了一个一致性哈希环的构建过程,对于OpenStack Swift存储,对应的Ring文件,其实就是一个一致性哈希环。
这篇文章讲述了OpenStack Swift Ring文件的构建原理。目前翻译了第一部分和第二部分,包含了最原始的算法,并最终引入虚拟节点,减少扩容时的数据移动

阅读全文 »

ArchLinux下网易云音乐会有偶然的白屏情况,是由于不支持某些emoji字体导致的,可以安装noto-fonts-emoji,然后配置一下字体即可解决:

sudo pacman -S noto-fonts-emoji

配置~/.config/fontconfig/conf.d/51-noto-color-emoji.conf文件:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
    <selectfont>
        <acceptfont>
            <pattern>
                <patelt name="family"><string>Noto Color Emoji</string></patelt>
            </pattern>
        </acceptfont>
    </selectfont>
    <match target="font">
        <test name="family">
            <string>Noto Color Emoji</string>
        </test>
        <edit name="scalable" mode="assign"><bool>true</bool></edit>
        <edit name="embeddedbitmap" mode="assign"><bool>true</bool></edit>
        <edit name="hinting" mode="assign"><bool>true</bool></edit>
        <edit name="hintstyle" mode="assign"><const>hintfull</const></edit>
    </match>
    <match target="pattern">
        <test name="family" qual="first" compare="contains">
            <string>emoji</string>
        </test>
        <edit mode="assign" name="color">
            <bool>true</bool>
        </edit>
        <edit mode="assign" name="family">
            <string>Noto Color Emoji</string>
        </edit>
    </match>
    <match target="pattern">
        <edit name="family" mode="prepend">
            <string>Noto Color Emoji</string>
        </edit>
    </match>
</fontconfig>

参考: https://blog.judge.moe/archives/90/

在使用普通用户执行需要超级用户权限的指令时,经常忘记前面加上sudo,等到命令输入完成,再加sudo很麻烦,可以绑定一个快捷方式快速输入最前面的sudo:
如果使用Bash,在~/.bashrc中加入:

bind '"\e\e":"\C-asudo \C-e"'

如果使用Zsh,在~/.zshrc中加入:

bindkey -s '\e\e' '\C-asudo \C-e'

生效后,只需要连续按两下ESC键,即可快速将sudo添加到命令最前端。

上一次说到Zend的词法分析,现在该轮到语法分析和中间代码生成部分了。一般情况下,词法分析和语法分析是在一起的过程,所以一般词法分析器和语法分析器是交织在一起的,共同运行。
PHP的语法分析器使用的是Bison。具体的语法分析器定义在 Zend/zend_language_parser.y文件中。

阅读全文 »
0%