<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Owais</title>
    <description>The latest articles on Forem by Owais (@desertthunder).</description>
    <link>https://forem.com/desertthunder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2074252%2F9c6dc823-bb69-4afd-9052-17b12c680067.png</url>
      <title>Forem: Owais</title>
      <link>https://forem.com/desertthunder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/desertthunder"/>
    <language>en</language>
    <item>
      <title>Dev Log Backlog</title>
      <dc:creator>Owais</dc:creator>
      <pubDate>Tue, 28 Oct 2025 13:16:03 +0000</pubDate>
      <link>https://forem.com/desertthunder/dev-log-backlog-f38</link>
      <guid>https://forem.com/desertthunder/dev-log-backlog-f38</guid>
      <description>&lt;h2&gt;
  
  
  Dev Log 2: 2025-10-27
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Yesterday
&lt;/h3&gt;

&lt;p&gt;I did a lot of work on beacon's constraint and solver system. This was after setting up completions and planning out a linting engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Today
&lt;/h3&gt;

&lt;p&gt;So far I worked extensively on extending the linting engine. You can read an overview about it &lt;a href="https://stormlightlabs.github.io/beacon/lsp/lint_rules.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The docstring parsing is mostly complete and code needs to be back ported into the &lt;a href="https://crates.io/crates/parserst" rel="noopener noreferrer"&gt;parserst&lt;/a&gt; crate I've made.&lt;/p&gt;

&lt;p&gt;Stub parsing and discovery has also been added with typeshed integration in the works. With time today I plan to setup caches for a lot of the data the LSP uses.&lt;/p&gt;

&lt;h4&gt;
  
  
  SkyPanel
&lt;/h4&gt;

&lt;p&gt;My goal today is to build a two pronged project to improve my experience on bluesky. It'll require me to learn about how the AT Protocol works in earnest. I was really enthusiastic about it when I got on the platform last year but didn't have a problem to solve but now I've got some deficiencies I want to address.&lt;/p&gt;

&lt;p&gt;Basically there will be a chrome extension that lets you build on the fly feeds and perform some saving and backup on posts, like links, videos, etc. It'll also let you view your feeds with a collapsed view per user, so you're not scrolling through an entire page of a single user's posts and reposts.&lt;/p&gt;

&lt;p&gt;The other half is a CLI that lets you read bluesky posts in the terminal. Gotta prototype with a CLI.&lt;/p&gt;

&lt;p&gt;You can see what I've started &lt;a href="https://github.com/stormlightlabs/SkyPanel" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dev Log 1: 2025-10-26
&lt;/h2&gt;

&lt;p&gt;This is my second post here on leaflet! I think today's log is a little more refined than yesterday. It's probably because the Dodgers won.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yesterday
&lt;/h3&gt;

&lt;p&gt;I worked on error boundaries in VoltX and scaffolded some observability enhancements.&lt;/p&gt;

&lt;p&gt;Most of my time was spent on workspace level LSP features. The foundation is a dependency graph and the Tarjan SCC (strongly connected components) algorithm. The LSP indexes the workspace, resolves imports, and handles a cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  Today
&lt;/h3&gt;

&lt;p&gt;As I continue to learn about type inference to solidify my understanding, I plan to keep pushing towards completing the LSP implementation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Static Analysis
&lt;/h4&gt;

&lt;p&gt;Control &amp;amp; data flow analysis using graphs (per function). This includes narrowing of flow and construction of union types for conditionals (each branch is a member).&lt;/p&gt;

&lt;p&gt;Handle PEP 484/585 type hints &amp;amp; annotations&lt;/p&gt;

&lt;p&gt;Work on diagnostics - I'm a little worried about this one, because I want to create useful messages and I know I'll be second guessing wording.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dev Log 0: 2025-10-25
&lt;/h2&gt;

&lt;p&gt;Today I'm working on two projects: &lt;a href="https://github.com/stormlightlabs/volt" rel="noopener noreferrer"&gt;VoltX.js&lt;/a&gt;, a web framework inspired by htmx and alpine, and &lt;a href="https://github.com/stormlightlabs/beacon" rel="noopener noreferrer"&gt;beacon&lt;/a&gt;, a LSP implementation and type system for Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beacon
&lt;/h3&gt;

&lt;p&gt;Yesterday I extracted and then expanded the rst parser and renderer that I wrote into a standalone published crate. Today I plan on reintegrating it.&lt;/p&gt;

&lt;p&gt;I've got a lot of reading to do. So far my work on the hindley milner system portion of the codebase feels like a blur. Lots of stuff I don't completely understand. There's a popular paper called Typing Haskell in Haskell that I'm going to try to get through today.&lt;/p&gt;

&lt;h3&gt;
  
  
  VoltX
&lt;/h3&gt;

&lt;p&gt;Today's all about developer experience and "delight." I want to make the tool as drop in as possible with powerful insights into the reactive lifecycle. So far I've finished error boundaries and even deployed a &lt;a href="https://voltx-demo.pages.dev" rel="noopener noreferrer"&gt;demo&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Asynchronous Python</title>
      <dc:creator>Owais</dc:creator>
      <pubDate>Mon, 25 Nov 2024 01:35:53 +0000</pubDate>
      <link>https://forem.com/desertthunder/asynchronous-python-2gjc</link>
      <guid>https://forem.com/desertthunder/asynchronous-python-2gjc</guid>
      <description>&lt;p&gt;This essay was originally posted &lt;a href="https://desertthunder.substack.com/p/async-python" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Asynchronous programming is the process of writing code that includes events that occur independently of the main flow of the program. So a process will begin, but the interpreter will continue to execute the next steps of the program. This allows us to do multiple things at the same time. In contrast, synchronous code is executed sequentially, or a single step at a time. Each statement is executed and the computation completed before moving on to the next. It is often easy to think of the functions that are being executed like an algebraic function, in which each operation/computation occurs in a predictable order. In other words, if we imagine each operation as a task, they are performed one at a time, with one finishing completely before another the next. If they're  always performed in the same order, the implementation of later tasks can assume that previous tasks finished error-free.&lt;/p&gt;

&lt;p&gt;Another model for task execution, is the multi-threaded model. each task is performed in a separate thread of control, managed by the operating system kernel. On systems with multiple processors or multiple cores, run truly concurrently. This is commonly referred to as preemptive multitasking.&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;In the async model, tasks execution order is interleaved with one another in a single thread. This is simpler than the threaded case because the programmer always knows that when one task is executing, another task is not. It is called cooperative multitasking. We'll discuss the implications of that later. For now, know that this makes an async thread subject to the Global Interpreter Lock (GIL). This is a mutex that ensures that there are no race conditions&lt;sup id="fnref2"&gt;2&lt;/sup&gt;. The work around for that to create multiple threads is a multithreading library.&lt;/p&gt;

&lt;p&gt;Asynchronous programming is relevant for processes/tasks dependent on computer resources outside the CPU. For example, HTTP resources require accessing the network and opening and closing files require disk access. Synchronous statements calls are called blocking (blocking calls), because they must be executed before the next statement runs.&lt;sup id="fnref3"&gt;3&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Here are some simple examples that ostensibly do the same things. We create a queue (remember, FIFO - first in first out), that contains tasks (simple operations), and then we iterate through the queue and execute the tasks. I've wrapped these in a simple &lt;code&gt;click&lt;/code&gt; CLI. See the README in the associated repo for instructions on installation.&lt;/p&gt;

&lt;p&gt;In the sync function, we create a queue and run a blocking worker function that processes tasks from the queue. We do this by using the standard library threading module and queue module, where each task is a simple pause using &lt;code&gt;time.sleep(1)&lt;/code&gt; to simulate a blocking operation. This demonstrates how a blocking worker running in a single thread processes tasks sequentially.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb67jb0356r1fxpje5ow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb67jb0356r1fxpje5ow.png" alt="synchronous worker" width="800" height="899"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the async function, we create an &lt;code&gt;asyncio&lt;/code&gt; queue and run a non-blocking worker function that processes tasks from the queue. In this case, we have two workers running concurrently, processing tasks from the queue. We're using a single-threaded event loop to run the workers concurrently. This demonstrates how non-blocking workers can run concurrently in a single thread while using the &lt;code&gt;asyncio&lt;/code&gt; module. asyncio's sleep function is used to simulate the time it may take to complete an operation like I/O-bound tasks or network requests. This is referred to as cooperative multitasking&lt;sup id="fnref4"&gt;4&lt;/sup&gt;, where the event loop continues execution while the task waits for whatever resource it needs. Another example of this is done via python generators, which use &lt;code&gt;yield&lt;/code&gt; (the task &lt;em&gt;yields&lt;/em&gt; control to the loop)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuhp1erewcgyaycry564.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuhp1erewcgyaycry564.png" alt="asynchronous worker" width="800" height="953"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HTTPx is a library that gives us both an async and synchronous interface. This can provide us with a good way to demonstrate the differences between two ways to write concurrent code when the tasks are not CPU-bound. Usually you'll see simple synchronous requests in python code executed by the requests package. The key differences in the synchronous case are the extensibility of the httpx Client object, and support for &lt;code&gt;http/2&lt;/code&gt;.  In the demo application (see &lt;code&gt;cli/http.py&lt;/code&gt;), you can compare the time to synchronously fetch the JSON data for all 30 MLB teams versus running the tasks concurrently using the &lt;code&gt;AsyncClient&lt;/code&gt; class from httpx.&lt;/p&gt;

&lt;p&gt;The differences between &lt;code&gt;http/1.1&lt;/code&gt; and &lt;code&gt;http/2&lt;/code&gt;, which come down to four major points: content prioritization, multiplexing, server push, and header compression&lt;sup id="fnref5"&gt;5&lt;/sup&gt;. Multiplexing does a lot to enhance the efficiency for developers, as it is a feature allow for a single tcp connection to be maintained between the server and client, where the client opens up multiple streams to fetch data. Server push lets the server send data to the client after sending a message detailing what content is coming. Header compression compresses redundant http header information using HPACK. When multiple requests are made, the small decreases in packet size can add up to decrease latency. Content prioritization on the other hand has more to do with web pages, as it allows the client to choose which content is loaded first (between static files like CSS or JavaScript).&lt;/p&gt;

&lt;p&gt;A common myth is that async python code is faster than synchronous due to concurrency. As mentioned previously, this is cooperative multitasking in a &lt;em&gt;single&lt;/em&gt; thread. Because it is cooperative, threads don't have CPU distributed evenly, as execution has to be relinquished by the task itself instead of interrupted by a governor like the operating system kernel. Cal Peterson demonstrates this when benchmarking synchronous and asynchronous servers[^2.] He notes that async servers don't need as many workers because they can use a single CPU. It's the latency caused by the yielding of a task that slows them down. He notes that throughput is determined by the amount of python replaced by native code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://hackernoon.com/asynchronous-python-45df84b82434" rel="noopener noreferrer"&gt;Async Python from Hackernoon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;500 Lines or Less: &lt;a href="https://aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html" rel="noopener noreferrer"&gt;A Web Crawler with Asyncio Coroutines&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Structured_concurrency" rel="noopener noreferrer"&gt;Structured Concurrency&lt;/a&gt;, used by an alternative to asyncio, Trio (&lt;a href="https://trio.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;docs&lt;/a&gt;). The pattern here is called the "nursery pattern," in which threads have clear entry and exit points and are encapsulated in constructs called nurseries. These ensure that the execution of the thread has completed before the process exits.&lt;sup id="fnref6"&gt;6&lt;/sup&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;Images of code from &lt;a href="https://carbon.now.sh/" rel="noopener noreferrer"&gt;carbon&lt;/a&gt;.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Fonseca, R. (2012). Async Programming [Class handout]. Brown University, CSCI 1680. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;“The Python GIL (Global Interpreter Lock) • Python Land Tutorial.” &lt;em&gt;Python Land&lt;/em&gt;, 18 Dec. 2021, &lt;a href="https://python.land/python-concurrency/the-python-gil" rel="noopener noreferrer"&gt;https://python.land/python-concurrency/the-python-gil&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Grinberg, Miguel. Sync vs. Async Python: What Is the Difference? &lt;a href="https://blog.miguelgrinberg.com/post/sync-vs-async-python-what-is-the-difference" rel="noopener noreferrer"&gt;https://blog.miguelgrinberg.com/post/sync-vs-async-python-what-is-the-difference&lt;/a&gt;. Accessed 24 Nov. 2024. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;“Cooperative Multitasking.” Wikipedia, 31 Jan. 2024. Wikipedia, &lt;a href="https://en.wikipedia.org/w/index.php?title=Cooperative_multitasking&amp;amp;oldid=1201426758" rel="noopener noreferrer"&gt;https://en.wikipedia.org/w/index.php?title=Cooperative_multitasking&amp;amp;oldid=1201426758&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;“HTTP/2 vs. HTTP/1.1.” Cloudflare.com, 2015, &lt;a href="https://www.cloudflare.com/learning/performance/http2-vs-http1.1/" rel="noopener noreferrer"&gt;https://www.cloudflare.com/learning/performance/http2-vs-http1.1/&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;Design and Internals — Trio 0.27.0+dev Documentation. &lt;a href="https://trio.readthedocs.io/en/latest/design.html#cancel-points-and-schedule-points" rel="noopener noreferrer"&gt;https://trio.readthedocs.io/en/latest/design.html#cancel-points-and-schedule-points&lt;/a&gt;. Accessed 24 Nov. 2024. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>python</category>
      <category>async</category>
      <category>concurrency</category>
      <category>http</category>
    </item>
  </channel>
</rss>
