<?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: Gergely B. B.</title>
    <description>The latest articles on Forem by Gergely B. B. (@errorport).</description>
    <link>https://forem.com/errorport</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%2F357382%2Fa3d8cee2-73d7-437b-b688-93f5ea90f6fe.png</url>
      <title>Forem: Gergely B. B.</title>
      <link>https://forem.com/errorport</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/errorport"/>
    <language>en</language>
    <item>
      <title>cpm-rs, a rust crate for Critical Path Method</title>
      <dc:creator>Gergely B. B.</dc:creator>
      <pubDate>Fri, 01 Apr 2022 20:10:27 +0000</pubDate>
      <link>https://forem.com/errorport/cpm-rs-a-rust-crate-for-critical-path-method-5flp</link>
      <guid>https://forem.com/errorport/cpm-rs-a-rust-crate-for-critical-path-method-5flp</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;The Critical Path Method is a widely used methodology to identify the rigid points of a graph of tasks, where the connections between the tasks are the dependencies. Some things cannot be started without finishing others. There are a lot of real-life examples for this case.&lt;/p&gt;

&lt;p&gt;The network of these tasks can be analyzed with different algorithms to get more detailed information about the 'batch', like selecting tasks for high priority. These tasks form a path in the graph alongside their connections. This path is called a 'critical path'. If any of the tasks on this path is being delayed it delays the whole batch, meaning the finishing time for the whole set of tasks will be late.&lt;/p&gt;

&lt;h1&gt;
  
  
  cpm-rs
&lt;/h1&gt;

&lt;p&gt;I do not want to bring up the details of the CPM here. There are a lot of very detailed articles and books about the methodology. This article aims to introduce the &lt;a href="https://crates.io/crates/cpm-rs" rel="noopener noreferrer"&gt;cpm-rs&lt;/a&gt; Rust crate.&lt;br&gt;
The goal is to have a well tested, reliable library that covers the CPM and still is optimized and scalable.&lt;/p&gt;

&lt;h1&gt;
  
  
  Aim
&lt;/h1&gt;

&lt;p&gt;This library should be able to be used in project-management tools and in automated task scheduling for large amount of progressive tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do we have
&lt;/h2&gt;

&lt;p&gt;At the moment, the latest published version is v0.1.6 and it is far away from being production-ready. The following features are working:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File parser for predefined tasks. May be removed later, it is a bit over-engineered and still not so well implemented.&lt;/li&gt;
&lt;li&gt;Critical path calculation.&lt;/li&gt;
&lt;li&gt;Calculation of number of maximum parallel tasks at a time. It means that the Scheduler can calculate the maximal number of parallel tasks in the batch.&lt;/li&gt;
&lt;li&gt;Indexed integer or floating point time units.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Scheduler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="nf"&gt;.add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CustomTask&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"Task_A"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="nf"&gt;.add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CustomTask&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"Sidetask_B"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Task_A"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
    &lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="nf"&gt;.add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CustomTask&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"Sidetask_C"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Task_B"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
    &lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="nf"&gt;.add_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CustomTask&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"Finish"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Sidetask_B"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"Sidetask_C"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
    &lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="nf"&gt;.schedule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What we need
&lt;/h2&gt;

&lt;p&gt;The following features are very crucial to have, but not yet implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependency circle check.&lt;/li&gt;
&lt;li&gt;Shiftable tasks.&lt;/li&gt;
&lt;li&gt;Graph visualization.&lt;/li&gt;
&lt;li&gt;Crate features.&lt;/li&gt;
&lt;li&gt;Proper unit tests.&lt;/li&gt;
&lt;li&gt;Stress tests.&lt;/li&gt;
&lt;li&gt;Resource-wise estimation.&lt;/li&gt;
&lt;li&gt;Priority-wise estimation.&lt;/li&gt;
&lt;li&gt;Task grouping.&lt;/li&gt;
&lt;li&gt;Resource type groups.&lt;/li&gt;
&lt;li&gt;Group priority.&lt;/li&gt;
&lt;li&gt;Resource state management.&lt;/li&gt;
&lt;li&gt;Actual time type unit types.&lt;/li&gt;
&lt;li&gt;OPTIMIZATION.&lt;/li&gt;
&lt;li&gt;CI/CD pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Call for contribution
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fiarzguk7m3yqpqwsdhgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fiarzguk7m3yqpqwsdhgw.png" alt="CPM-rs cover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you feel the ambition to participate in this project, you are warmly welcome to contribute!&lt;br&gt;
If you have any questions, please open a pull request on the repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/cpm-rs" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fcrates%2Fv%2Fcpm-rs.svg" alt="Crates.io"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/errorport/cpm-rs" rel="noopener noreferrer"&gt;GIT repository&lt;/a&gt;&lt;br&gt;
&lt;a href="https://crates.io/crates/cpm-rs" rel="noopener noreferrer"&gt;crates.io page&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://hbr.org/1963/09/the-abcs-of-the-critical-path-method" rel="noopener noreferrer"&gt;The ABCs of the Critical Path Method by F. K. Levy, G. L. Thompson, and J. D. Wiest&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cpm</category>
      <category>rust</category>
      <category>backend</category>
      <category>schedule</category>
    </item>
    <item>
      <title>EXOSTAT: minimal system statusbar</title>
      <dc:creator>Gergely B. B.</dc:creator>
      <pubDate>Sun, 29 Mar 2020 21:54:06 +0000</pubDate>
      <link>https://forem.com/errorport/exostat-minimal-system-statusbar-1im</link>
      <guid>https://forem.com/errorport/exostat-minimal-system-statusbar-1im</guid>
      <description>&lt;h2&gt;
  
  
  interrupt_call(&amp;amp;pain, &amp;amp;timer(Time::from_sec(1.5))).meltdown();
&lt;/h2&gt;

&lt;p&gt;I'm using tiling window managers since the beginning of my BSc. Obviously using Windows for software development, especially in case of embedded development is a horror. Another thing to mention is, floating windows and user interface interruptions can make me crazy. Sometimes when I am forced to use windows it's so hard to take control over my patience. People around me said that I am just hysterical (and maybe I am) but since I could use Linux on my working computer not just on my personal ones, my life gone calm.&lt;/p&gt;

&lt;p&gt;Why should I process so many irrelevant, visual information every time I want to do a simple job? I spend my entire life behind monitors. 10-16 hours a day, I mean. I just simply don't have a nervous capacity for all of the interrupting popup windows, the icons, the &lt;a href="https://www.tutorialspoint.com/windows10/windows10_gui_basics.htm"&gt;clicky-clicky GUIs&lt;/a&gt; and the repetitive, manual workflows that proprietary software offers as "user friendly" features. I don't need guides and wizards.&lt;/p&gt;

&lt;p&gt;I had the same problem with Gnome, KDE, XFCE and other floating window managers too. If you feel the same, try i3, dwm or other tiling wms.&lt;/p&gt;

&lt;p&gt;This post is not about the ultimate solution of mine, just about a slice of it: my statusbar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Gzgrh0jj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mxued5em7pgpq1eetsqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gzgrh0jj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mxued5em7pgpq1eetsqs.png" alt="exodwm with exostatus" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am using dwm by &lt;a href="http://suckless.org"&gt;suckless.org&lt;/a&gt;. To be honest, I have my own fork with some extra patches and my own config: &lt;a href="https://github.com/errorport/exodwm/"&gt;exodwm&lt;/a&gt;&lt;br&gt;
I tried &lt;a href="https://i3wm.org/"&gt;i3&lt;/a&gt; before and it was very handy. I think it's very good for a cold start if you are new to tiling wms.&lt;/p&gt;

&lt;h2&gt;
  
  
  complexity === wasting resources
&lt;/h2&gt;

&lt;p&gt;Soon we will realize that, bloatwares and over-engineered solutions are as dangerous to our environment and health as toxic waste, wrong resource management and so on. Ok, this sentence leads to somewhere else. When I design a system I try to keep this in mind and make my product as simple as possible, to get the same functionality with the possibly lowest complexity. It's just a simple rule just like I don't leave the toliet dirty.&lt;/p&gt;

&lt;p&gt;So let's talk about your desktop! Please drop every window down to the task bar and count every informative fields that you see now. Every text, icon, numbers, everything. Now try to sort them by their informative level. Suppose that we've got a ranklist with 3 levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Information that are relevant in every workflow.&lt;/li&gt;
&lt;li&gt;Information that are relevant in a specific workflow.&lt;/li&gt;
&lt;li&gt;Irrelevant information. (If you have a "start" or "Applications" text near the taskbar's leader icon, it counts one.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think you can decide what conclusion you should get after this.&lt;/p&gt;

&lt;p&gt;I tried to collect only those information that are relevant in all the workflows, put them into my taskbar and that's all. Therefore I have the following on my desktop screen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyboard layout. (Sometimes I have to write letters on my native language.)&lt;/li&gt;
&lt;li&gt;CPU temperature.&lt;/li&gt;
&lt;li&gt;Network RX/TX stats for all interfaces. (KBytes/sec, icon colors indicates if there were traffic in the previous iteration)&lt;/li&gt;
&lt;li&gt;Battery capacity in percentage and AC plug status (icon color).&lt;/li&gt;
&lt;li&gt;Current time.&lt;/li&gt;
&lt;li&gt;Current time in binary format. (just for fun)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---P7IRbk6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yys27zd4r84wuns2d8ua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---P7IRbk6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yys27zd4r84wuns2d8ua.png" alt="exostat" width="867" height="18"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice and simple. Comfy.&lt;/p&gt;

&lt;h2&gt;
  
  
  under the hood
&lt;/h2&gt;

&lt;p&gt;The guys behind &lt;a href="https://dwm.suckless.org/"&gt;dwm&lt;/a&gt; were wise enough to implement a simple feature for this statusbar. dwm displays xroot's window name in this place, so the only thing I had to manage to fill xroot with a well forged string.&lt;/p&gt;

&lt;p&gt;I decided to make this project in Rust. For system stats I chose &lt;a href="https://crates.io/crates/systemstat"&gt;systemstat&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here you can find my repository for &lt;a href="https://github.com/errorport/exostat"&gt;exostat&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  happy ever after
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6-0Sb6Do--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lu5j2chl5zpy6cdu4ty3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6-0Sb6Do--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lu5j2chl5zpy6cdu4ty3.png" alt="how it looks like" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, after all of this, I found piece...&lt;br&gt;
Ok, I have lot of plans with my own desktop environment setup, but I can say, using this tiling setting with this simple-to-modify statusbar,my workflow became fast and even to use this environment can be even recreational.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--StcV6Hw_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yxc0nukp3foaz9jtgsy6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--StcV6Hw_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yxc0nukp3foaz9jtgsy6.png" alt="stay tuned!" width="500" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>minimal</category>
      <category>rust</category>
      <category>design</category>
    </item>
  </channel>
</rss>
