<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>ValarMorghulis.IO</title>
    <link>https://valarmorghulis.io/</link>
    <description>Recent content on ValarMorghulis.IO</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>valarmorghulis.io </copyright>
    <lastBuildDate>Tue, 07 Apr 2026 12:00:00 +0800</lastBuildDate><atom:link href="https://valarmorghulis.io/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Run stdio MCP server with Python in Claude Desktop</title>
      <link>https://valarmorghulis.io/tech/202604-run-stdio-mcp-with-python-in-claude-desktop/</link>
      <pubDate>Tue, 07 Apr 2026 12:00:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202604-run-stdio-mcp-with-python-in-claude-desktop/</guid>
      <description>
        
          
            &lt;p&gt;Mostly, the stdio MCP servers are configurated in &lt;code&gt;claude_desktop_config.json&lt;/code&gt; using &lt;code&gt;mcp-remote&lt;/code&gt; via node.js .  Here are a few notes if you want to run stdio MCP server with Python in Claude Desktop.&lt;/p&gt;
&lt;h2 id=&#34;run-with-uv&#34;&gt;run with uv&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;uv run xxx&lt;/code&gt; or &lt;code&gt;uv tool run xxx&lt;/code&gt; to run a stdio server, the config like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;your-mcp&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;uv&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;run&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;your-mcp-exeutable&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You may change the &lt;code&gt;args&lt;/code&gt; to &lt;code&gt;[&amp;quot;tool&amp;quot;, &amp;quot;run&amp;quot;, &amp;quot;your-mcp-exeutable&amp;quot;]&lt;/code&gt; if you are your mcp servers should be run with &lt;code&gt;uv tool&lt;/code&gt;. If the mcp server is one of the executables in a package, change &lt;code&gt;args&lt;/code&gt; to &lt;code&gt;[&amp;quot;tool&amp;quot;, &amp;quot;run&amp;quot;, &amp;quot;--from&amp;quot;, &amp;quot;your-package&amp;quot;, &amp;quot;your-mcp-exeutable&amp;quot;]&lt;/code&gt;&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>OpenClaw matrix plugin setup in docker</title>
      <link>https://valarmorghulis.io/tech/202603-openclaw-matrix-plugin-setup-in-docker/</link>
      <pubDate>Tue, 17 Mar 2026 12:00:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202603-openclaw-matrix-plugin-setup-in-docker/</guid>
      <description>
        
          
            &lt;p&gt;The OpenClaw matrix plugin has a npm dependency issue, it will cause error like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;[plugins] matrix: crypto runtime bootstrap failed: Cannot find module &amp;#39;@vector-im/matrix-bot-sdk&amp;#39;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;Require stack:  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;- /app/extensions/matrix/src/matrix/deps.ts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Use &lt;code&gt;openclaw plugins install @openclaw/matrix&lt;/code&gt; as mentioned if OpenClaw official document always result the docker container failed to start. I managed to use matrix in docker with the methods below:&lt;/p&gt;
&lt;h2 id=&#34;method-1&#34;&gt;Method 1&lt;/h2&gt;
&lt;p&gt;Just directly do &lt;code&gt;npm install&lt;/code&gt; in matrix extension dir:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; /app/extensions/matrix &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You need to ensure &lt;code&gt;&amp;quot;/app/extensions/matrix&amp;quot;&lt;/code&gt; for &lt;code&gt;plugins.load.paths&lt;/code&gt; in openclaw.json .&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>AI Glasses and the eye doctor</title>
      <link>https://valarmorghulis.io/comic/202601-ai-glasses-and-the-eye-doctor/</link>
      <pubDate>Fri, 30 Jan 2026 09:13:59 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/comic/202601-ai-glasses-and-the-eye-doctor/</guid>
      <description>
        
          
            &lt;p&gt;&lt;figure&gt;
  &lt;picture&gt;

    
      
        
        
        
        
        
        
    &lt;img
      loading=&#34;lazy&#34;
      decoding=&#34;async&#34;
      alt=&#34;&amp;amp;amp;quot;AI Glasses and the eye doctor&#34;
      
        class=&#34;image_figure image_internal image_unprocessed&#34;
        src=&#34;ai-glasses-and-the-eye-doctor.png&#34;
      
      
    /&gt;

    &lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Don&#39;t take it serious! You can always give code yes to get it cooling down.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>GEO is Not the Next Generation of SEO</title>
      <link>https://valarmorghulis.io/view/202601-geo-vs-seo/</link>
      <pubDate>Fri, 23 Jan 2026 19:30:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/view/202601-geo-vs-seo/</guid>
      <description>
        
          
            &lt;p&gt;In the rapidly shifting landscape of digital marketing, a new buzzword has taken center stage: GEO, or Generative Engine Optimization.&lt;/p&gt;
&lt;p&gt;If you read the latest marketing newsletters, you’ll see everyone looking into GEO today. It is being pitched as the shiny &amp;quot;next generation&amp;quot; of SEO—the silver bullet to draw traffic in an era where users are talking to chatbots instead of typing into search bars. However, this narrative is misleading. While the intention behind optimizing for AI is valid, the concept of GEO as it stands today is very ill-constructed.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Python dependencies states managed via uv(illustrated)</title>
      <link>https://valarmorghulis.io/tech/202511-python-dependencies-states-managed-via-uv/</link>
      <pubDate>Mon, 10 Nov 2025 15:19:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202511-python-dependencies-states-managed-via-uv/</guid>
      <description>
        
          
            &lt;p&gt;Several dependency management file types are available in the Python ecosystem—&lt;code&gt;requirements.txt&lt;/code&gt;, &lt;code&gt;uv.lock&lt;/code&gt;, &lt;code&gt;pyproject.toml&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;uv&lt;/code&gt;, we can handle most of them. Here is a transition graph showing how to move from one state to another using &lt;code&gt;uv&lt;/code&gt; commands.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://valarmorghulis.io/tech/202511-python-dependencies-states-managed-via-uv/python-dependencies-states-managed-via-uv.svg&#34;&gt;&lt;figure&gt;
  &lt;picture&gt;

    
      
        
        
        
        
        
        
    &lt;img
      loading=&#34;lazy&#34;
      decoding=&#34;async&#34;
      alt=&#34;Python dependencies states managed via uv&#34;
      
        class=&#34;image_figure image_internal image_unprocessed&#34;
        src=&#34;python-dependencies-states-managed-via-uv.svg&#34;
      
      
    /&gt;

    &lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note: &amp;quot;&lt;code&gt;libs in env&lt;/code&gt;&amp;quot; refers to installed dependencies in a virtual environment created by &lt;code&gt;uv venv&lt;/code&gt;.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Deploy models on SGLang with CPU only</title>
      <link>https://valarmorghulis.io/tech/202508-deploy-models-on-sglang-with-cpu-only/</link>
      <pubDate>Sun, 03 Aug 2025 17:19:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202508-deploy-models-on-sglang-with-cpu-only/</guid>
      <description>
        
          
            &lt;p&gt;If you just want to serve an LLM model with WSL2 on your old laptop, this is for you.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.sglang.ai/references/cpu.html&#34;&gt;The official document have introduced how to build and run SGLang in CPU with docker&lt;/a&gt;. But there several issues with the image built based on the tutorial:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SGLang deps on VLLM, which is not installed&lt;/li&gt;
&lt;li&gt;SGLang code requires NUMA to run&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I build a image to meet the above problems, which is available at &lt;a href=&#34;https://hub.docker.com/r/metaphorprojects/sglang-cpu&#34;&gt;https://hub.docker.com/r/metaphorprojects/sglang-cpu&lt;/a&gt; .&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Run MiniCPM4 with CPU only</title>
      <link>https://valarmorghulis.io/tech/202506-run-minicpm4-with-cpu-only/</link>
      <pubDate>Sun, 08 Jun 2025 20:19:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202506-run-minicpm4-with-cpu-only/</guid>
      <description>
        
          
            &lt;p&gt;This is a guide for serving the &lt;a href=&#34;https://huggingface.co/openbmb/MiniCPM4-0.5B&#34;&gt;MiniCPM4 0.5b&lt;/a&gt; model with CPU only(in my  laptop WSL Ubuntu 24.04).&lt;/p&gt;
&lt;p&gt;The model is served by llama.cpp, and I break down it for several steps.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download the model from hf&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;huggingface-cli download openbmb/MiniCPM4-0.5B
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Install(and compile) the llama.cpp&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# build llama.cpp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/ggml-org/llama.cpp.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt install python3-dev build-essential cmake libcurl4-openssl-dev
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;cmake -B build  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;cmake --build build --config Release
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# prepare llama tools&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;uv venv --python&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;3.12 .venv
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;uv pip install -r requirements/requirements-convert_hf_to_gguf.txt --index-strategy unsafe-best-match
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Convert the downloaded safetensors model to gguf format&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# the default model location of huggingface-cli&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;python convert_hf_to_gguf.py &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;~/.cache/huggingface/hub/models--openbmb--MiniCPM4-0.5B/snapshots/ebf6ddf19764646a49d94e857fb4eb439f35ecfb/ &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;--outfile /path/to/minicpm4-0.5b.gguf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Serve the gguf file with llama.cpp&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;build/bin/llama-server --model /path/to/minicpm4-0.5b.gguf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here you can call the model with OpenAI API protocol at http//127.0.0.1:8080/v1 .&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Call MCP Server(stdio) directly in the shell</title>
      <link>https://valarmorghulis.io/tech/202505-call-mcp-server-stdio-in-the-shell/</link>
      <pubDate>Mon, 19 May 2025 19:30:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202505-call-mcp-server-stdio-in-the-shell/</guid>
      <description>
        
          
            &lt;p&gt;&lt;code&gt;stdio&lt;/code&gt; is one of the transport mechanisms MCP(Model Context Protocol) natively supports. Actually &lt;code&gt;stdio&lt;/code&gt; is the only transport mechanism Claude Desktop supports currently(as in May, 2025). This article will show you how to call a MCP server in the shell, without &lt;code&gt;mcp dev&lt;/code&gt; or any third party tools,  only with &lt;code&gt;echo &amp;gt;&lt;/code&gt; or copying/pasting JSONRPC message directly.&lt;/p&gt;
&lt;p&gt;First, let&#39;s write a very simple MCP server(get_time.py) to get the current time:&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Measuring the CPU and Memory Usage for  Python subprocess</title>
      <link>https://valarmorghulis.io/tech/202505-measuring-cpu-memory-python-subprocess/</link>
      <pubDate>Wed, 14 May 2025 22:10:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202505-measuring-cpu-memory-python-subprocess/</guid>
      <description>
        
          
            &lt;p&gt;The article talks about a method for measuring the resources used by a process invoked by &lt;code&gt;subprocess.run&lt;/code&gt; or &lt;code&gt;subprocess.Popen&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can use &lt;code&gt;psutil&lt;/code&gt; to get realtime usage data of a process. Using &lt;code&gt;psutil&lt;/code&gt; may not provide accurate resource measurements for short-lived processes, as it samples usage at intervals and can miss brief spikes. We want a method to get the final resource usage of a process after it finishes.&lt;/p&gt;
&lt;p&gt;The method leverages &lt;code&gt;multiprocessing.Process&lt;/code&gt; to wrap the calling of &lt;code&gt;subprocess.run&lt;/code&gt; or &lt;code&gt;subprocess.Popen&lt;/code&gt;,  and get the resource usage by calling &lt;code&gt;resource.getrusage(resource.RUSAGE_CHILDREN)&lt;/code&gt; of the wrapper process. For example,&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>tac -- the ignored reverse of cat</title>
      <link>https://valarmorghulis.io/tech/202503-tac/</link>
      <pubDate>Tue, 18 Mar 2025 08:00:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202503-tac/</guid>
      <description>
        
          
            &lt;p&gt;When &lt;code&gt;grep&lt;/code&gt; a very large log file to find the last occurrence of some string, it is much than efficient to back iterate the files from the last line than methods using &lt;code&gt;tail&lt;/code&gt; or &lt;code&gt;tail -n&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And I just found &lt;code&gt;tac&lt;/code&gt; from coreutils, best suiting the job. &lt;code&gt;tac&lt;/code&gt; is the reverse of &lt;code&gt;cat&lt;/code&gt;, the job I mentioned above can be done via:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;tac very-large-log-file.log|grep -m 1 some-string
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is very useful. And most important thing is that I didn&#39;t realize the solution is lying there ignored in the &lt;code&gt;coreutils&lt;/code&gt; all the time.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Python version of Rust Result Sum Type</title>
      <link>https://valarmorghulis.io/tech/202501-python-version-of-rust-sum-type-result/</link>
      <pubDate>Sun, 19 Jan 2025 21:00:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202501-python-version-of-rust-sum-type-result/</guid>
      <description>
        
          
            &lt;p&gt;I try to implement a Python version of the &lt;a href=&#34;https://doc.rust-lang.org/std/result/enum.Result.htm&#34;&gt;Result&amp;lt;T, E&amp;gt; sum type in rust&lt;/a&gt; which can be used with match/case pattern matching.&lt;/p&gt;
&lt;p&gt;The pattern matching with sub-patterns like &lt;code&gt;case Err(e)&lt;/code&gt; could be implemented in Python with the &lt;code&gt;__match_args__&lt;/code&gt; dunder attribute. This is how &lt;code&gt;Result[T, E]&lt;/code&gt;, &lt;code&gt;OK()&lt;/code&gt; and &lt;code&gt;Err()&lt;/code&gt; defined:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;import typing
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;T = typing.TypeVar(&amp;#39;T&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;E = typing.TypeVar(&amp;#39;E&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;class Result[T, E]:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    __match_args__ = (&amp;#39;_val&amp;#39;,)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    def __init__(self, val):
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        self._val = val
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;class Ok[T](Result[T, ...]):
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    pass
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;class Err[E](Result[..., E]):
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    pass
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Below is the match/case block, note that if you have different types value to match(like different Error types), the guard(if statement behind the case pattern) must be used.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Run wasm built with wasm-pack with pythonmonkey</title>
      <link>https://valarmorghulis.io/tech/202501-wasm-with-pythonmonkey/</link>
      <pubDate>Fri, 03 Jan 2025 20:00:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202501-wasm-with-pythonmonkey/</guid>
      <description>
        
          
            &lt;p&gt;I have been trying to run wasm code built with wasm-pack with pythonmonkey,  a Mozilla &lt;a href=&#34;https://firefox-source-docs.mozilla.org/js/index.html&#34;&gt;SpiderMonkey&lt;/a&gt; JavaScript engine embedded into the Python Runtime.&lt;/p&gt;
&lt;p&gt;Consider a &lt;code&gt;lib.rs&lt;/code&gt; as follow:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;use&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wasm_bindgen&lt;/span&gt;::&lt;span class=&#34;n&#34;&gt;prelude&lt;/span&gt;::&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#[wasm_bindgen]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;pub&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fn&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;i32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;i32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span class=&#34;kt&#34;&gt;i32&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With &lt;a href=&#34;https://rustwasm.github.io/docs/wasm-pack/&#34;&gt;wasm-pack&lt;/a&gt;, we can build the src code to wasm&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;wasm-pack build --target nodejs --no-typescript
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We will get a .wasm file and a .js wrapper file. The case here is that we can not instantiate the .wasm directly, which will get us errors like &lt;code&gt;No module named &#39;__wbindgen_placeholder__&#39;&lt;/code&gt;, or &lt;code&gt;import object field &#39;__wbindgen_init_externref_table&#39; is not a Function&lt;/code&gt;. We should instead import the .js wrapper file, and use exported interfaces.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Combine mesop with natural abilities of flask</title>
      <link>https://valarmorghulis.io/tech/202412-mesop-flask-app/</link>
      <pubDate>Mon, 23 Dec 2024 22:00:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202412-mesop-flask-app/</guid>
      <description>
        
          
            &lt;p&gt;&lt;a href=&#34;https://google.github.io/mesop&#34;&gt;mesop&lt;/a&gt; is popular with AI apps, since is can be used to build web apps with Python without frontend works.&lt;/p&gt;
&lt;p&gt;mesop is developed upon the popular frontend framework flask. How about combine the natural abilities of flask while developing with mesop? Let do a little research.&lt;/p&gt;
&lt;h2 id=&#34;access-flask-request-instanceincluding-headers-cookies&#34;&gt;Access flask request instance(including headers, cookies)&lt;/h2&gt;
&lt;p&gt;In any mesop page, you may simply access &lt;code&gt;flask.request&lt;/code&gt;, &lt;code&gt;flask.request.cookies&lt;/code&gt;, &lt;code&gt;flask.request.headers&lt;/code&gt; by importing flask.  For example&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;import flask
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;import mesop as me
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;@me.page(
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    path=&amp;#34;/home&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    security_policy=me.SecurityPolicy(  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        dangerously_disable_trusted_types=True)  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;)  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;def page():  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    with me.box():  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        for k, v in flask.request.cookies.items():
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            me.text(f&amp;#39;{k}: {v}&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above code will display the cookies inside a box component.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Create a partial model definition of a pydantic model</title>
      <link>https://valarmorghulis.io/tech/202412-pydantic-partial-model/</link>
      <pubDate>Mon, 09 Dec 2024 23:00:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202412-pydantic-partial-model/</guid>
      <description>
        
          
            &lt;p&gt;Sometimes I want to create a partial model definition of a pydantic model. For example, if I want to expose a database model from API, some of the fields I would like to keep in secret, or I just want to expose very few fields in a summary API. I don&#39;t want to write model definition twice. I would like to write something like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;ModelExposed = partial_model(ModelSource, &amp;#39;ModelExposed&amp;#39;, include=[&amp;#34;title&amp;#34;, &amp;#34;description&amp;#34;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So I write a funciton as below to do it, including support of passing list of excluding fields, copying computed fields and validators.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>psql vs. mysql shell command cheatsheet</title>
      <link>https://valarmorghulis.io/tech/202412-psql-vs-mysql-shell-cheatsheet/</link>
      <pubDate>Thu, 05 Dec 2024 00:20:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202412-psql-vs-mysql-shell-cheatsheet/</guid>
      <description>
        
          
            &lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;MySQL&lt;/th&gt;
          &lt;th&gt;Postgres&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;list databases&lt;/td&gt;
          &lt;td&gt;SHOW DATABASES&lt;/td&gt;
          &lt;td&gt;\l&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;change to a database&lt;/td&gt;
          &lt;td&gt;USE &amp;lt;db_name&amp;gt;&lt;/td&gt;
          &lt;td&gt;\c &amp;lt;db_name&amp;gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;list tables&lt;/td&gt;
          &lt;td&gt;SHOW TABLES&lt;/td&gt;
          &lt;td&gt;\dt&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;describe a table&lt;/td&gt;
          &lt;td&gt;DESC &amp;lt;table_name&amp;gt;&lt;/td&gt;
          &lt;td&gt;\d &amp;lt;table_name&amp;gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;show the create table sql&lt;/td&gt;
          &lt;td&gt;SHOW CREATE TABLE &amp;lt;table_name&amp;gt;&lt;/td&gt;
          &lt;td&gt;pg_dump -st &amp;lt;table_name&amp;gt; &amp;lt;db_name&amp;gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;explain a query&lt;/td&gt;
          &lt;td&gt;EXPLAIN &amp;lt;sql_statement&amp;gt;&lt;/td&gt;
          &lt;td&gt;EXPLAIN &amp;lt;sql_statement&amp;gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;expanded(vertical) display&lt;/td&gt;
          &lt;td&gt;\G&lt;/td&gt;
          &lt;td&gt;\gx&lt;br&gt;or use \x to switch&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;get help&lt;/td&gt;
          &lt;td&gt;? &amp;lt;SQL STATEMENT&amp;gt;&lt;br&gt;HELP &amp;lt;SQL STATEMENT&amp;gt;&lt;/td&gt;
          &lt;td&gt;\h &amp;lt;SQL STATEMENT&amp;gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;get active processes&lt;/td&gt;
          &lt;td&gt;SHOW [FULL] PROCESSLIST;&lt;/td&gt;
          &lt;td&gt;SELECT pid, usename, state, query, query_start, application_name FROM pg_stat_activity WHERE state = &#39;active&#39;;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;kill a process&lt;/td&gt;
          &lt;td&gt;KILL &amp;lt;pid&amp;gt;;&lt;/td&gt;
          &lt;td&gt;SELECT pg_terminate_backend(&amp;lt;pid&amp;gt;);&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;quit shell&lt;/td&gt;
          &lt;td&gt;QUIT&lt;/td&gt;
          &lt;td&gt;\q&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Deploy next.js using pm2 cluster mode(and with docker)</title>
      <link>https://valarmorghulis.io/tech/202409-next-js-using-pm2-cluster-mode/</link>
      <pubDate>Tue, 03 Sep 2024 21:37:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202409-next-js-using-pm2-cluster-mode/</guid>
      <description>
        
          
            &lt;p&gt;We can simply start the Next.js application using &lt;code&gt;next start&lt;/code&gt;. However, when facing higher traffic demands in practical use, how can we deploy Next.js using a multi-process approach?&lt;/p&gt;
&lt;p&gt;We can achieve this using the cluster mode of pm2. The cluster mode is a powerful way of scaling Node.js applications, allowing you to start multiple processes, all listening on the same port. How do we do this? First, we can create a .json file to describe the pm2 task (named pm2.json):&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Use python -m http.server in SSL</title>
      <link>https://valarmorghulis.io/tech/202409-python-http-serveri-in-ssl/</link>
      <pubDate>Mon, 02 Sep 2024 19:26:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202409-python-http-serveri-in-ssl/</guid>
      <description>
        
          
            &lt;p&gt;&lt;code&gt;python -m http.server&lt;/code&gt; is a very convenient command line tool to start an ad-hoc static web server. This tool is very useful when you want to develop small web applications or serve static files.&lt;/p&gt;
&lt;p&gt;But it does not support SSL. A lot of modern web applications as well as browser features require a secured connection. So I want to wrap &lt;code&gt;http.server&lt;/code&gt; in SSL and try making it simple to use.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>The contextvars and the chain of asyncio tasks in Python</title>
      <link>https://valarmorghulis.io/tech/202408-the-asyncio-tasks-and-contextvars-in-python/</link>
      <pubDate>Sat, 10 Aug 2024 17:26:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202408-the-asyncio-tasks-and-contextvars-in-python/</guid>
      <description>
        
          
            &lt;p&gt;In Python, the contextvars is somehow like thread local, but mostly for coroutines. But will the context itself be kept consistent in a chain of asyncio tasks? Let&#39;s find out.&lt;/p&gt;
&lt;h2 id=&#34;contextvars&#34;&gt;contextvars&lt;/h2&gt;
&lt;p&gt;Let&#39;s have a rough review of the &lt;code&gt;contextvars&lt;/code&gt; in Python. The &lt;code&gt;contextvars&lt;/code&gt; module provides a way to maintain a context across a chain of function calls, natively supported with asyncio. For example&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;contextvars&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contextvars&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ContextVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;var&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;sub2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;in sub2, &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;=}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sub1 set&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;sub1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;in sub1, &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;=}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sub1 set&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sub2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;main set&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sub1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;in main, &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;=}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The output would be&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Unix pipe to clipboard with WSL, and in UTF-8</title>
      <link>https://valarmorghulis.io/tech/202404-unix-pipe-to-clipboard-with-wsl-and-in-utf8/</link>
      <pubDate>Wed, 17 Apr 2024 22:47:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202404-unix-pipe-to-clipboard-with-wsl-and-in-utf8/</guid>
      <description>
        
          
            &lt;p&gt;WSL is good, it will be even better if we can pipe stdout directly into Windows host’s clipboard. Just like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    ./myscript.sh | to-my-clipboard.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that xclip requires X, so it is not an option. From WSL, we have direct access to Windows executables. The easiest method would be using &lt;code&gt;clip.exe&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    ./myscript.sh | clip.exe
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The method works fine if you don’t touch CJK characters or emojis. &lt;code&gt;clip.exe&lt;/code&gt; didn’t handle the encoding well since the default codepage in Windows is not 65001(UTF-8). The command below would probably break&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Several tips for better working with Python in Excel</title>
      <link>https://valarmorghulis.io/tech/202310-python-in-excel/</link>
      <pubDate>Tue, 10 Oct 2023 10:21:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202310-python-in-excel/</guid>
      <description>
        
          
            &lt;p&gt;After enrolled for Python in Excel preview, now I can type &lt;code&gt;=py(&lt;/code&gt; in any Excel cell to write some Python code. Python in Excel doesn&#39;t have detailed documents, only &lt;em&gt;Get Started&lt;/em&gt; tutorials, like &lt;a href=&#34;https://support.microsoft.com/en-gb/office/introduction-to-python-in-excel-55643c2e-ff56-4168-b1ce-9428c8308545&#34;&gt;link 1&lt;/a&gt;, &lt;a href=&#34;https://support.microsoft.com/en-gb/office/get-started-with-python-in-excel-a33fbcbe-065b-41d3-82cf-23d05397f53d&#34;&gt;link 2&lt;/a&gt;, or articles talking about topics like &lt;code&gt;pandas&lt;/code&gt;, &lt;code&gt;matplotlib&lt;/code&gt;, &lt;code&gt;seaborn&lt;/code&gt;, etc., it may confuse you when you want to do some real work in an unfamiliar environment. The article notes several tips from my understanding of Python in Excel.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Analyze robots.txt with Python Standard Library</title>
      <link>https://valarmorghulis.io/tech/202309-analyze-robotstxt-with-python/</link>
      <pubDate>Sun, 24 Sep 2023 21:13:59 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202309-analyze-robotstxt-with-python/</guid>
      <description>
        
          
            &lt;p&gt;If haven&#39;t searched both &amp;quot;python&amp;quot; and &amp;quot;robots.txt&amp;quot; in the same input box, I would not ever know that Python Standard Library could parse robots.txt with &lt;a href=&#34;https://docs.python.org/3/library/urllib.robotparser.html&#34;&gt;urllib.robotparser&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But the official document of &lt;code&gt;urllib.robotparser&lt;/code&gt; doesn&#39;t go into detail. With the document, you could check whether a url can be fetch with a robot with &lt;code&gt;robot_parser_inst.can_fetch(user_agent, url)&lt;/code&gt; if you are building a crawler bot yourself. But if you want to do some statistics about robots.txt, like what most disallowed path for Googlebot are, from the document not only you don&#39;t know how to do it, but also you don&#39;t know whether the lib is able to do it.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Process AWS Kinesis Firehose data with Python</title>
      <link>https://valarmorghulis.io/tech/202309-aws-firehose-json-python/</link>
      <pubDate>Mon, 11 Sep 2023 21:13:59 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202309-aws-firehose-json-python/</guid>
      <description>
        
          
            &lt;p&gt;Pipelining streamed data events directly into Amazon S3 via the AWS Kinesis Firehose service is convenient and efficient. And we could use Python with boto3 to consume the data directly from S3. This allows for seamless storage of your data, ensuring its integration and accessibility.&lt;/p&gt;
&lt;p&gt;Mostly, we are dealing with JSON-formatted event logs. But there is one tiny stone in the shoe for logs feeding from AWS Kinesis Firehose, there is no newline between consecutive log entries.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Thoughts on the fading away of the age of IE</title>
      <link>https://valarmorghulis.io/view/202307-thoughts-on-the-fading-away-of-the-age-of-ie/</link>
      <pubDate>Sat, 22 Jul 2023 06:22:59 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/view/202307-thoughts-on-the-fading-away-of-the-age-of-ie/</guid>
      <description>
        
          
            &lt;p&gt;Nowadays, as it pleased most frontend engineers, making web pages/applications compatible with IE Browser is not required almost everywhere.&lt;/p&gt;
&lt;p&gt;Internet Explorer, especially the lower versions, is inconsistent with W3C standards, barely has developer toolchains, and therefore very hard to debug. But the anti-modern frontend legacy browsers didn’t easily die. If you had checked browser distribution in recent years, you would notice that IE always had a reasonable proportion, not much, but also not in a trend towards zero in a short period.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>The curious cases of json_extract</title>
      <link>https://valarmorghulis.io/tech/202004-the-curious-cases-of-json-extract/</link>
      <pubDate>Sat, 25 Apr 2020 21:00:00 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/202004-the-curious-cases-of-json-extract/</guid>
      <description>
        
          
            &lt;p&gt;json_extract is a function for extract data from a JSON document both in MySQL and MariaDB. The function normally works fine, for example&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;num&amp;#34;: 42, &amp;#34;list&amp;#34;: [1, 2, 3], &amp;#34;obj&amp;#34;: {&amp;#34;name&amp;#34;: &amp;#34;Edward Stark&amp;#34;}}&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;select&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json_extract&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;$.num&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json_extract&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;$.list&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json_extract&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;$.obj&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;------+-----------+--------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;------+-----------+--------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;42&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Edward Stark&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;------+-----------+--------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But when it comes to a single JSON string, the results of json_extract is not always as expected. We shall investigate the different cases.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Contextvars and Thread local</title>
      <link>https://valarmorghulis.io/tech/201904-contextvars-and-thread-local/</link>
      <pubDate>Fri, 12 Apr 2019 11:13:59 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/201904-contextvars-and-thread-local/</guid>
      <description>
        
          
            &lt;p&gt;Here in the post, I will share some examples about the contextvars (new in Python 3.7) and thread local.&lt;/p&gt;
&lt;h2 id=&#34;default-value&#34;&gt;Default Value&lt;/h2&gt;
&lt;p&gt;In the module level, use ContextVar.set or directly setattr for a thread local variable, won&#39;t successfully set a default value, the value set won&#39;t take effect in another thread.&lt;/p&gt;
&lt;p&gt;To ensure a default value, for contextvars&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;contextvars&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;context_var&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contextvars&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ContextVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;context_var&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;for thread local, a sub class of thread.local need to be declared&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>The Tiny Chips from Chinese Hackers: When Falsifiability meets Public Perception</title>
      <link>https://valarmorghulis.io/view/20181028-the-tiny-chips-from-chinese-hackers/</link>
      <pubDate>Sun, 28 Oct 2018 06:22:59 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/view/20181028-the-tiny-chips-from-chinese-hackers/</guid>
      <description>
        
          
            &lt;p&gt;&lt;figure&gt;
  &lt;picture&gt;

    
      
        
        
        
        
        
        
    &lt;img
      loading=&#34;lazy&#34;
      decoding=&#34;async&#34;
      alt=&#34;from https://pixabay.com/en/processor-cpu-computer-chip-board-2217771/&#34;
      
        class=&#34;image_figure image_internal image_unprocessed&#34;
        src=&#34;https://valarmorghulis.io/images/view/processor-2217771_1920.jpg&#34;
      
      
    /&gt;

    &lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;During the 2018 Chinese National Day Holidays, Bloomberg Business Week reported that Chinese hackers planted microchips into motherboards supplying for data center servers of tech giants Apple and Amazon. The original Bloomberg post is available at &lt;a href=&#34;https://www.bloomberg.com/news/features/2018-10-04/the-big-hack-how-china-used-a-tiny-chip-to-infiltrate-america-s-top-companies&#34;&gt;https://www.bloomberg.com/news/features/2018-10-04/the-big-hack-how-china-used-a-tiny-chip-to-infiltrate-america-s-top-companies&lt;/a&gt;, and &lt;a href=&#34;https://www.bloomberg.com/news/articles/2018-10-04/the-big-hack-amazon-apple-supermicro-and-beijing-respond&#34;&gt;Amazon, Apple, Super Micro and the Chinese Government all have denied the hack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As I followed the related posts, I found despite there may(or may not) be a hack on the motherboard chips, surely the event happening and growing is a big hack on the public perception. The story of tiny chip hacking is falsifiable in the lab of tech giants like Amazon or Apple, but the story itself spreading in the public, the ongoing process, is not falsifiable. There will never be clear yes/no for the story(even the yes/no could be very sure at the lab), as more and more people read the story(and followed posts), forget the detail or even a summary of the story, remember only some keywords at last, there will be untrustworthy about the chips and conspiracy theories about hackers in the public perception.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>The Ponzi Software Development Scheme</title>
      <link>https://valarmorghulis.io/view/20180107-the-ponzi-software-development-scheme/</link>
      <pubDate>Sun, 07 Jan 2018 02:13:59 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/view/20180107-the-ponzi-software-development-scheme/</guid>
      <description>
        
          
            &lt;p&gt;The metaphor Ponzi Software Development Scheme, came to me after I have been read about a post from CACM, &lt;a href=&#34;https://cacm.acm.org/magazines/2017/12/223060-the-death-of-big-software/fulltext&#34;&gt;The Death of Big Software&lt;/a&gt;. The traditional big softwares will die away, because they are easily growing to become too hard to maintain, and will be replaced by cloud or microservices architecture based softwares.&lt;/p&gt;
&lt;p&gt;But will cloud or microservices save big software projects from failure? I rather say, &lt;a href=&#34;https://en.wikipedia.org/wiki/No_Silver_Bullet&#34;&gt;no silver bullets&lt;/a&gt;, neither cloud nor microservices. Actually, here the “big” software projects are misleading, software projects fails not because they are big(big repos of code, big set of connected components, big set of requirements/features), software projects fails when they fall into the Ponzi software development scheme. Of course, big software projects are prone to evolve into the Ponzi software development scheme.&lt;/p&gt;
          
          
        
      </description>
    </item>
    
    <item>
      <title>Mongodb(via MongoEngine) join query with aggregate</title>
      <link>https://valarmorghulis.io/tech/201701-mongodb-join-query-with-aggregate/</link>
      <pubDate>Mon, 09 Jan 2017 02:13:59 +0800</pubDate>
      
      <guid>https://valarmorghulis.io/tech/201701-mongodb-join-query-with-aggregate/</guid>
      <description>
        
          
            &lt;p&gt;Since Mongodb 3.2 and MongoEngine 0.9, we can use $aggregate command to perform join queries on multiple collections in a database. This post would be a simple tutorial for join queries on Mongodb(via MongoEngine in Python) with examples.&lt;/p&gt;
&lt;h2 id=&#34;models-setup&#34;&gt;Models Setup&lt;/h2&gt;
&lt;p&gt;Let&#39;s consider models defined as below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;import random
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;import mongoengine
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;class User(mongoengine.Document):
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    meta = {&amp;#34;indexes&amp;#34;: [&amp;#39;rnd&amp;#39;]}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    name = mongoengine.StringField()
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    rnd = mongoengine.FloatField(default=random.random)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;class Group(mongoengine.Document):
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    meta = {&amp;#34;indexes&amp;#34;: [&amp;#39;rnd&amp;#39;]}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    name = mongoengine.StringField()
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    rnd = mongoengine.FloatField(default=random.random)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;class Relation(mongoengine.Document):
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    meta = {&amp;#34;indexes&amp;#34;: [&amp;#39;user_id&amp;#39;, &amp;#39;group_id&amp;#39;]}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    user_id = mongoengine.ObjectIdField()
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    group_id = mongoengine.ObjectIdField()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note:&lt;/p&gt;
          
          
        
      </description>
    </item>
    
  </channel>
</rss>
