Eventlet with Playwright

I was developing an LLM application recently. the front-end javascript client interacts with the back-end Python server via socket.io:

# Back-end
eventlet                  0.33.3                   pypi_0    pypi
python-engineio           4.5.1                    pypi_0    pypi
python-socketio           5.8.0                    pypi_0    pypi
playwright                1.36.0                   pypi_0    pypi
unstructured              0.8.1                    pypi_0    pypi

# Front-end
socket.io                 4.6.0    

# System
Linux platform 5.10.0-19-cloud-amd64 #1 SMP 
Debian 5.10.149-2 (2022-10-21) x86_64 GNU/Linux

The initial issue I found is that the socket.io emit function call cannot be received by the front-end client.

I guess it was caused by the system sync operations, so I added “eventlet.monkey_patch()” and turned the system modules ‘green’. Then I found the emit issue was gone.

The term “green” is related to a Python environment that facilitates the operation of green threads. The standard python library does not support the execution model that allows green threads to mutually yield control of the CPU in the same way as eventlet does. To address this, the developers behind eventlet had to modify certain segments of the Python standard library—a process they aptly term as “patching”.

Consequently, if you are considering using eventlet within your application, you will need to explicitly render the modules you wish to import as “green”.

Nevertheless, upon adding the ‘monkey_patch’, I encountered another bug: the ‘sync_playwright’ context manager was hanging and failing to exit properly. I proceeded to trace the stack, where I discovered that ‘monkey_patch’ was altering the system threading libraries globally. However, I simply needed to apply ‘green’ threading to the socketio library, so I changed “eventlet.monkey_patch()” to “socketio = eventlet.import_patched(‘socketio’)”.

The revised script appears as follows:

# Original 
import eventlet
eventlet.monkey_patch() # Modify the global library

# Modified and worked well
import eventlet
socketio = eventlet.import_patched("socketio") # Modify the specific library

PS: for MacOS, try adding this at the beginning of your code:

import sys
if sys.platform == "darwin":
    import selectors
    selectors.DefaultSelector = selectors.PollSelector

Leviathan II

In the natural state, some people may be stronger or wiser than others, but no one is strong enough or wise enough not to fear death by violence. Since everyone instinctively needs more, and in fact everything is insufficient, people need to fight for more, all against all.

However, fighting in a natural state is not the optimal solution. Driven by self-interest at its most essential, people will want to end fights – “the zeal that tends toward peace is the fear of death, the desire for the things necessary for a comfortable life and the diligent hope of acquiring them”. When death is becoming a threat, people will do everything possible to protect themselves, so this is the highest necessity to avoid death and become the source of power. People cede their degrees of freedom to authority in order to protect their own survival and rights. However, everyone has different demands for individual rights. How to coordinate the relationship between people and authority?

Rousseau proposed the theory of “general will” to resolve the relationship between people and authority. The development of society makes it necessary for society to develop a common force that protects the individual’s personal and property. Rousseau believes that people’s rights such as freedom and equality belong to individuals, but the law that collects the will of all people belongs to the national level. On the premise of excluding the rich or powerful groups from curbing the expression of personal will, individuals form a general will by fully expressing their will, and then rise to “law” through a “judge” with divine status, so as to promote the formation of a reasonable and legitimate state power source.

But even so, the “general will” is still insufficient to represent the will of all citizens. So authority compartmentalize people and confer different identities to different people. These identities are apparently not equal, although some authorities do not admit this. It is through the distinction between the hierarchy that the authority achieves solid rule.

By means of the Jewish national cleansing, the will of the head of state was almost fulfilled. Some Eastern countries also fought protracted wars in which people were divided into the capitalist and the proletariat. In the subsequent massacre in Rwanda, Hutu and Husi slaughtered each other, eventually leading to genocide.

It is human nature to seek sanctuary and social belonging. By joining a collective, one can gain power, a sense of security, and overcome the powerlessness in the face of an increasingly highly organized society. These identities become their psychological refuge. To gain group acceptance through some kind of identity loyalty.

As a Chinese, the easiest challenge to “general will” is patriotism. Everything seems to end up being classified as “patriotic” or “unpatriotic.” From whether you can go out during the epidemic isolation, to whether you buy a Huawei phone.

Naturally, these “general wills” are not groundless but carefully deliberated by some people who have an axe to grind. Given the multiple identities of each of us, how should identity loyalty be prioritized? Do we have the right to decide our own identities? Can we fuck the bewitching and demagoguery of those careerists off?

Mr. Tagore’s words may serve as an answer to this question: “Patriotism cannot be our last spiritual refuge; The last refuge is human nature. I will not buy glass at the price of diamonds, and I will never allow patriotism to triumph over humanity as long as I live.”

NLP Road Map

Caution!

  • The relationship among keywords could be interpreted in ambiguous ways since they are represented in the format of a semantic mind-map. Please just focus on KEYWORD in square box, and deem them as the essential parts to learn.
  • The work of containing a plethora of keywords and knowledge within just an image has been challenging. Thus, please note that this roadmap is one of the suggestions or ideas.
  • You are eligible for using the material of your own free will including commercial purpose but highly expected to leave a reference (https://github.com/graykode/nlp-roadmap).
Probability and Statistics
Continue reading

Something interesting

不管哪个领域,都可以在上升期做科研,在平稳期做业务,在饱和期做教育,显然Andrew Ng是个明白人。

No matter what field you are in, you can do research in the growing period, dedicate into the industry in the steady period, and develop education in the saturation period. Obviously, Andrew Ng is a sensible person.

楽しい

按理说,我们二十五六岁,买车买房,工作体面,不能再抱怨了。但是房,车,体面,这些都是大路商品。我有,其他人可能有我的一百倍,一千倍还多。但是十年的青春时光,每个人都只有一次。

我希望看到这里的人,可以记得未来很重要,但是二十多岁一定要快意,可以努力奋斗也可以玩,可以富有也可以贫穷,但不能扭曲,要快意。

当你26岁决定自己要不要成为30岁的博士时,要记得这件事。

To be honest, we have a decent job, house, car at the age of 25, should not complain more. However, cars/houses/good jobs, all of them, are general commodities, others may have them of ten times or even of hundred times than of what I have. But the ten years of youth, everyone has only one time.

So, please remember this thing, when you are 26 years old and decide whether you want to be a 30-year-old Doctor.

Semiring

import numpy as np
import networkx as nx
from functools import reduce
import matplotlib.pyplot as plt

connect_graph = np.array([[0, 1, 0, 0, 0], 
                          [0, 0, 0, 1, 0], 
                          [0, 0, 0, 1, 0], 
                          [0, 0, 0, 0, 1], 
                          [0, 0, 1, 0, 0]])

def ring_add(a, b):
    return a or b

def ring_multi(a, b):
    return a and b

def dot_product(i, j):
    row = connect_graph[i]
    column = connect_graph[:,j]
    return reduce(ring_add, [ring_multi(a, b) for a, b in zip(row, column)])

def next_generation(connect_graph):
    candidate_number = connect_graph.shape[0]

    new_connect_graph = np.zeros((candidate_number, candidate_number))

    for i in range(candidate_number):
        for j in range(candidate_number):
            new_connect_graph[i][j] = dot_product(i,j)
            
    return new_connect_graph

new_connect_graph = next_generation(connect_graph)

def draw_graph(connect_graph):
    G = nx.DiGraph()
    
    candidate_number = connect_graph.shape[0]
    
    node_name = list(range(candidate_number))
    G.add_nodes_from(node_name)
    
    for i in range(candidate_number):
        for j in range(candidate_number):
            if connect_graph[i][j]:
                G.add_edge(i, j)

    nx.draw(G, with_labels=True)

    plt.show()

draw_graph(new_connect_graph)