<?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>DEV Community: Or Yaacov</title>
    <description>The latest articles on DEV Community by Or Yaacov (@oryaacov).</description>
    <link>https://dev.to/oryaacov</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%2F740683%2F8b902fbb-a7b6-40be-bc91-59f95b4fd431.jpg</url>
      <title>DEV Community: Or Yaacov</title>
      <link>https://dev.to/oryaacov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oryaacov"/>
    <language>en</language>
    <item>
      <title>Ted talks that everyone should hear — part 1</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Wed, 24 Sep 2025 11:43:49 +0000</pubDate>
      <link>https://dev.to/oryaacov/ted-talks-that-everyone-should-hear-part-1-31h2</link>
      <guid>https://dev.to/oryaacov/ted-talks-that-everyone-should-hear-part-1-31h2</guid>
      <description>&lt;p&gt;Well, I don’t want to start with spoilers, and I definitely can’t retell the story better than Tim Box himself. I highly recommend that you start by watching the TED Talk:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ZidGozDhOjg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=ZidGozDhOjg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, what did I learn from it…&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%2Frsgnnbx7x1pr4mh2psa9.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%2Frsgnnbx7x1pr4mh2psa9.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Everyone feels anxiety
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;There are those that don’t feel anxiety, there are two very distinct groups, the first group, dead people, the second group (to his words) would be those we might refer to as Psychopaths&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everyone is an individual, wired differently, with their own set of abilities or inabilities. But the things that we, as humans — or in other words, Homo sapiens — have in common due to evolution are the same set of feelings, fears, and base instincts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is feeling anxious is negative?
&lt;/h2&gt;

&lt;p&gt;I completely agree with what he said. Experiencing high levels of anxiety over a long period of time is clearly not positive.&lt;br&gt;
But in the short term — whether it’s about an interview, technology, or taking a big step — it just means that the situation matters. And congratulations: you’re not ignoring it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How should we look at anxiety
&lt;/h2&gt;

&lt;p&gt;I completely agree with what he said. Experiencing high levels of anxiety over a long period of time is clearly not positive.&lt;br&gt;
But in the short term — whether it’s about an interview, technology, or taking a big step — it just means that the situation matters. And congratulations: you’re not ignoring it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How should we look at anxiety
&lt;/h2&gt;

&lt;p&gt;I personally think he described anxiety in the perfect way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Think of your mind as a ship, every ship has a captain and a crew, in this analogy the captain is your logical rational conscious part of your thinking, the part that knows where you wish to go, and why, and fair idea to how to get there. The crew, the people the people that has its hands on all the things that stair and sail our ship, is the subconscious.&lt;br&gt;
Your crew sail the ship by triggering the appropriate emotional responses&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;lets look at the examples he gave, for example, if we feel:&lt;br&gt;
&lt;strong&gt;somethings is dangerous&lt;/strong&gt; — Fear is triggered. You feel uncomfortable, so you move away from the danger, back to safety.&lt;br&gt;
(But remember: docking keeps a ship safe, but that’s not what ships are made for)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the believe that someone wronged you&lt;/strong&gt; — A crew member triggers anger, shifting your attention toward taking the necessary action to right the wrong.&lt;/p&gt;

&lt;p&gt;So what about &lt;strong&gt;anxiety&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;When anxiety is triggered, it’s your crew telling you that something is too important to lose focus on. For example, you have a job interview. Your crew recognizes how important it is, and they make sure it stays at the top of your mind so it doesn’t get ignored or forgotten.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;it’s the crew saying to the captain you need to pay attention for this&lt;/p&gt;
&lt;/blockquote&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%2F7h8uelpn0n8kiqvmf79o.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%2F7h8uelpn0n8kiqvmf79o.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why shouldn’t we ignore it?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;when you ignore someone with an important message they might just start to speak louder to get heard, if you continue to ignore them, they might start to shout&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I completely agree with this idea. And beyond that — why should we ignore what our subconscious is trying to tell us? Whether it’s a new business idea, a relationship, a big decision, a new technology changing the market, or a career issue — your crew is saying: “Hey, pay attention to this, because now is the right time.”&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;and the funny thing is, when you start listening to what your minds trying to tell you, it can stop shouting, when your crew stop shouting the captain can be heard&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My conclusions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When you feel anxious, it’s not a bad thing. It doesn’t mean something negative. It simply means that the topic or decision you’re anxious about is &lt;strong&gt;important&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you feel anxious, understand that this is your crew telling you, hey don’t ignore it! build actions items, &lt;strong&gt;Research. Plan. Build. Talk. Communicate. Consult. Trust your instincts. Make a decision.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember: as a Homo sapiens, anxiety is just another tool in your toolbox. It exists to help you reach your goals and desires&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are the captain sailing this ship. The crew is there to help you. You’re all on the same team. You know what your goal is — so communicate with your team, start sailing, and at the end of the day, try even enjoy the journey and not only to enjoy the destination…&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>howistartedmycompany</category>
      <category>anxiety</category>
      <category>selfimprovement</category>
    </item>
    <item>
      <title>Ted talks that everyone should hear - part 1</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Tue, 23 Sep 2025 22:31:50 +0000</pubDate>
      <link>https://dev.to/oryaacov/ted-talks-that-everyone-should-hear-part-1-424o</link>
      <guid>https://dev.to/oryaacov/ted-talks-that-everyone-should-hear-part-1-424o</guid>
      <description>&lt;p&gt;Well, I don’t want to start with spoilers, and I definitely can’t retell the story better than Tim Box himself. I highly recommend that you start by watching the TED Talk:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ZidGozDhOjg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=ZidGozDhOjg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, what did I learn from it…&lt;/p&gt;

&lt;h2&gt;
  
  
  Everyone feels anxiety
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;There are those that don’t feel anxiety, there are two very distinct groups, the first group, dead people, the second group (to his words) would be those we might refer to as Psychopaths&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everyone is an individual, wired differently, with their own set of abilities or inabilities. But the things that we, as humans — or in other words, Homo sapiens — have in common due to evolution are the same set of feelings, fears, and base instincts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is feeling anxious is negative?
&lt;/h2&gt;

&lt;p&gt;I completely agree with what he said. Experiencing high levels of anxiety over a long period of time is clearly not positive.&lt;br&gt;
But in the short term — whether it’s about an interview, technology, or taking a big step — it just means that the situation matters. And congratulations: you’re not ignoring it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How should we look at anxiety
&lt;/h2&gt;

&lt;p&gt;I personally think he described anxiety in the perfect way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Think of your mind as a ship, every ship has a captain and a crew, in this analogy the captain is your logical rational conscious part of your thinking, the part that knows where you wish to go, and why, and fair idea to how to get there. The crew, the people the people that has its hands on all the things that stair and sail our ship, is the subconscious.&lt;br&gt;
Your crew sail the ship by triggering the appropriate emotional responses&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;lets look at the examples he gave, for example, if we feel:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;somethings is dangerous&lt;/strong&gt; — Fear is triggered. You feel uncomfortable, so you move away from the danger, back to safety.&lt;br&gt;
(But remember: docking keeps a ship safe, but that’s not what ships are made for)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The believe that someone wronged you&lt;/strong&gt; — A crew member triggers anger, shifting your attention toward taking the necessary action to right the wrong.&lt;/p&gt;

&lt;p&gt;So what about &lt;strong&gt;anxiety&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;When anxiety is triggered, it’s your crew telling you that something is too important to lose focus on. For example, you have a job interview. Your crew recognizes how important it is, and they make sure it stays at the top of your mind so it doesn’t get ignored or forgotten.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;it’s the crew saying to the captain you need to pay attention for this&lt;/p&gt;
&lt;/blockquote&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%2Fcqapqnw85a6tvdfeml3u.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%2Fcqapqnw85a6tvdfeml3u.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why shouldn’t we ignore it?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;when you ignore someone with an important message they might just start to speak louder to get heard, if you continue to ignore them, they might start to shout&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I completely agree with this idea. And beyond that — why should we ignore what our subconscious is trying to tell us? Whether it’s a new business idea, a relationship, a big decision, a new technology changing the market, or a career issue — your crew is saying: “Hey, pay attention to this, because now is the right time.”&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;and the funny thing is, when you start listening to what your minds trying to tell you, it can stop shouting, when your crew stop shouting the captain can be heard&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My conclusions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When you feel anxious, it’s not a bad thing. It doesn’t mean something negative. It simply means that the topic or decision you’re anxious about &lt;strong&gt;is important&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you feel anxious, understand that this is your crew telling you, hey don’t ignore it! build actions items, &lt;strong&gt;Research. Plan. Build. Talk. Communicate. Consult. Trust your instincts. Make a decision&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember: as a Homo sapiens, anxiety is just another tool in your toolbox. It exists to help you reach your goals and desires&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are the captain sailing this ship. The crew is there to help you. You’re all on the same team. You know what your goal is — so communicate with your team, start sailing, and at the end of the day, try even enjoy the journey and not only to enjoy the destination… &lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2F6dq1q6zerabztq3my20t.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%2F6dq1q6zerabztq3my20t.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>learning</category>
      <category>mentalhealth</category>
    </item>
    <item>
      <title>How to profile your multi-threaded python production code programmatically</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Sun, 24 Dec 2023 01:20:28 +0000</pubDate>
      <link>https://dev.to/oryaacov/how-to-profile-your-multi-threaded-running-python-code-programmatically-collect-periodically-and-analyze-the-results-5fh3</link>
      <guid>https://dev.to/oryaacov/how-to-profile-your-multi-threaded-running-python-code-programmatically-collect-periodically-and-analyze-the-results-5fh3</guid>
      <description>&lt;p&gt;Profiling multi-threaded Python applications can be challenging, especially in production environments. Unfortunately, 90% of the guides don’t explain how to really do it, especially with remote production multi-threaded code and no cli, and they will lead you to use something like &lt;code&gt;python -m cProfile -s time my_app.py &amp;lt;args&amp;gt;&lt;/code&gt;&lt;br&gt;
Don't worry, this is not another one of those.&lt;/p&gt;

&lt;p&gt;So why is it “hard” to do? You can’t always run your program in production using the command-line interface (CLI), and cProfile only offers limited support for multi-threaded programming.&lt;/p&gt;
&lt;h2&gt;
  
  
  So, How to do Multi-Threading profiling?
&lt;/h2&gt;

&lt;p&gt;To perform multi-threading profiling, we can use one of the following approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sum different threads’ stats together to create one set of statistics using &lt;code&gt;stats.add()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a separate profiler for each thread.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since our program is built from 3 different engine threads, I will cover only the second approach in this guide.&lt;/p&gt;

&lt;p&gt;So, I created the following utility that allows me to create my threads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import cProfile
import threading
import time

class ProfilerManager:
    def __init__(self, is_enabled, dump_interval_seconds, profiler_dir_path):
        self._is_enabled = is_enabled
        self._logger = "YOUR LOGGER"
        self._profiler_dir_path = profiler_dir_path
        self._profiler_dump_interval_seconds = dump_interval_seconds

        if self._profiler_dump_interval_seconds &amp;lt;= 0:
            self._logger.warning('invalid _profiler_dump_interval_seconds value {}, setting default'.format(self._profiler_dump_interval_seconds))
            self._profiler_dump_interval_seconds = 60   

        self._profilers = {}

    def thread_with_profiler(self, target, tag):
       if not self._is_enabled:
              return threading.Thread(target=target)

        self._disable_profiler_if_exists(tag)

        profiler = cProfile.Profile()

        self._profilers[tag] = profiler

        return threading.Thread(target=self._target_with_profiler(target, profiler, tag))

    def run(self, target, tag):
        if not self._is_enabled:
            return target

        profiler = cProfile.Profile()

        self._profilers[tag] = profiler

        return self._target_with_profiler(target, profiler, tag)

    def _disable_profiler_if_exists(self, tag):
        if tag in self._profilers:
            self._logger.warning('tag {} already exists, disabling, and overriding with new target'.format(tag))
            existing_profiler = self._profilers[tag]
            self._disable_profiler(existing_profiler, tag)

    def _target_with_profiler(self, target, profiler, tag):
        def target_with_profiler():
            self._enable_profiler(profiler, tag)
            target()
            self._disable_profiler(profiler, tag)

        return target_with_profiler

    def _enable_profiler(self, profiler, tag):
        self._logger.debug('enabling profiler {}'.format(tag))
        profiler.enable()

    def _disable_profiler(self, profiler, tag):
        self._logger.debug('disabling profiler {}'.format(tag))
        profiler.disable()

    def _dump_periodic_profilers(self):
        while True:
            time.sleep(self._profiler_dump_interval_seconds)

            self._logger.trace("dumping profiles")

            for tag, profiler in self._profilers.items():
                dump_file_path = '{}/{}.dump'.format(self._profiler_dir_path, tag)
                self._logger.trace("dumping profile, {}".format(dump_file_path))

                profiler.dump_stats(dump_file_path)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s take a look at the &lt;code&gt;thread_with_profiler&lt;/code&gt; use which is similar to &lt;code&gt;threading.Thread&lt;/code&gt; the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ip_manager_thread = profiler_manager.thread_with_profiler(target=self._run_ip_monitor, tag='ip_manager')
ip_manager_thread.start()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;let’s do a quick dive into &lt;code&gt;thread_with_profiler&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def thread_with_profiler(self, target, tag):
        if not self._is_enabled:
            return threading.Thread(target=target)

        self._disable_profiler_if_exists(tag)

        profiler = cProfile.Profile()

        self._profilers[tag] = profiler

        return threading.Thread(target=self._target_with_profiler(target, profiler, tag))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All that this function does is disable the profiler with the same tag, in case it already exists. It creates a new profiler and a new thread, then runs &lt;code&gt;_target_with_profiler&lt;/code&gt;, which is the real magic behind the scenes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def _target_with_profiler(self, target, profiler, tag):
      def target_with_profiler():
          self._enable_profiler(profiler, tag)
          target()
          self._disable_profiler(profiler, tag)

      return target_with_profiler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, we create and return a new function wrapper that our thread will execute. All that the wrapper does is enable the profiler (start it), call your actual function, and disable it when/if it ends.&lt;/p&gt;

&lt;p&gt;Then, we have the following function, which actually dumps the current stats to files by tags every X seconds&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    def _dump_periodic_profilers(self):
        while True:
            time.sleep(self._profiler_dump_interval_seconds)

            self._logger.trace("dumping profiles")

            for tag, profiler in self._profilers.items():
                dump_file_path = '{}/{}.dump'.format(self._profiler_dir_path, tag)
                self._logger.trace("dumping profile, {}".format(dump_file_path))

                profiler.dump_stats(dump_file_path)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so, now that we got how this all thing works, let’s see a full use example!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def async_worker1():
  #work

def async_worker2():
  #work

def main_worker():
  #work

def main():
    profiler_manager = ProfilerManager(is_enabled=True, dump_interval_seconds=10, profiler_dir_path="/var/logs")
    profiler_manager.thread_with_profiler(target=self._run_ip_monitor, tag='async_worker1')
    profiler_manager.thread_with_profiler(target=self._run_ip_monitor, tag='async_worker2')

   profiler_manager.run(target=self._run_ip_monitor, tag='main_worker')profiler_manager.thread_with_profiler(target=self._run_ip_monitor, tag='ip_manager')

if __name__ == '__main__':
    main()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;happy profiling! :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>cprofile</category>
      <category>multithreading</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Deep .NET  -  Iteration: for vs foreach</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Sat, 02 Sep 2023 14:46:53 +0000</pubDate>
      <link>https://dev.to/oryaacov/deep-net-iteration-for-vs-foreach-4h1j</link>
      <guid>https://dev.to/oryaacov/deep-net-iteration-for-vs-foreach-4h1j</guid>
      <description>&lt;p&gt;I choose to start from one of the most common and basic things, Iteration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FShiTU-5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ow2v7o5hjzrpb3903ajg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FShiTU-5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ow2v7o5hjzrpb3903ajg.png" alt="Image description" width="104" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will explore how .NET iterates over &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; and over an &lt;code&gt;Array&amp;lt;T&amp;gt;&lt;/code&gt; and see what the differences are between iteration with a for and a foreach loop .&lt;/p&gt;

&lt;p&gt;But before we will start, let’s go over &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; and foreach and understand how each of them works&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TxlDPE9_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4l6pp5ikc855qkc8gan9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TxlDPE9_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4l6pp5ikc855qkc8gan9.png" alt="Image description" width="591" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The List class stores our items in an internal array named &lt;code&gt;_items&lt;/code&gt;, when we are creating a new list without any parameter, &lt;code&gt;_items&lt;/code&gt; is assigned to an empty array of T.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5IGmHy3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akw5yg301lj9uzsb4ow6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5IGmHy3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akw5yg301lj9uzsb4ow6.png" alt="Image description" width="272" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By adding an item into the array&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fjuIdA5V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hiza61rylc72tu32do63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fjuIdA5V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hiza61rylc72tu32do63.png" alt="Image description" width="367" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.NET starts by updating the version of the array (the _version variable keeps changing by an increment of 1 every time the array is modified so it will be possible to keep track when the collection has been modified).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;_size&lt;/code&gt; variable acts as a virtual size for our list, while the physical size is actually the length of the &lt;code&gt;_items&lt;/code&gt; array, called Capacity.&lt;br&gt;
So every time that we are adding an item into the list it ensures that the capacity is big enough to store another item and if it is , then the new item will be assigned.&lt;/p&gt;

&lt;p&gt;Every time the virtual size is bigger than the capacity, &lt;code&gt;AddWithResize&lt;/code&gt; method is being called:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iNOP5yaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/if95kbwv77bw1cjplky9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iNOP5yaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/if95kbwv77bw1cjplky9.png" alt="Image description" width="311" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jcJdUik2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gsol7ylbztmr4ks1wwti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jcJdUik2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gsol7ylbztmr4ks1wwti.png" alt="Image description" width="720" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This ensures that the next minimum size will be bigger then the current one plus 1 since we wish to add a new item into the list.&lt;/p&gt;

&lt;p&gt;Then the function calls to &lt;code&gt;EnsureCapacity&lt;/code&gt;, which sets the new capacity into the default one (&lt;code&gt;DefaultCapacity=4&lt;/code&gt;) in case &lt;code&gt;_items&lt;/code&gt; is an empty array, or doubles &lt;code&gt;_items&lt;/code&gt; size in case that &lt;code&gt;_items&lt;/code&gt; is not empty.&lt;/p&gt;

&lt;p&gt;That’s the most basic explanation to how List was implemented and the goal is to cover 3 basic points&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; uses an internal array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;Capacity(_items.Length)&lt;/code&gt; of the List is different then the &lt;code&gt;Count(_size)&lt;/code&gt; of the list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The list keeps an updated version variable that keeps track of changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  The foreach loop
&lt;/h2&gt;

&lt;p&gt;Many different collections such as &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; or &lt;code&gt;Dictionary&amp;lt;T&amp;gt;&lt;/code&gt; can be iterated by a foreach loop, because their class implements one of the following interfaces: &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.ienumerable"&gt;System.Collections.IEnumerable &lt;/a&gt; or &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1"&gt;System.Collections.Generic.IEnumerable&lt;/a&gt; and satisfies the following conditions:&lt;/p&gt;

&lt;p&gt;· has the public parameterless &lt;code&gt;GetEnumerator&lt;/code&gt; method whose return type is either class, struct, or interface type,&lt;/p&gt;

&lt;p&gt;· the return type of the &lt;code&gt;GetEnumerator&lt;/code&gt; method has the public Current property and the public parameterless MoveNext method whose return type is &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.boolean"&gt;Boolean&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Foreach loop works as &lt;strong&gt;the following example: (the following example is not the real .NET implantation)&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xDnGU1j9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pdhcva2r7iobadt5aha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xDnGU1j9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pdhcva2r7iobadt5aha.png" alt="Image description" width="411" height="411"&gt;&lt;/a&gt;&lt;br&gt;
So every initialization starts by calling to the &lt;code&gt;GetEnumurator()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--79hhhkCa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jj3yi2ebxhqccj29mhkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--79hhhkCa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jj3yi2ebxhqccj29mhkw.png" alt="Image description" width="329" height="42"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which creates a new Enumerator struct and passes the current list as an argument:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7aWWDNj---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6tqh4piaw7l4a3rq22f4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7aWWDNj---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6tqh4piaw7l4a3rq22f4.png" alt="Image description" width="500" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Important to mention that struct is not a reference type, and it’s important to understand the difference between the two - &lt;a href="https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/value-types-and-reference-types"&gt;you can read more about that here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After initializing the Enumerator and assigning the value, the MoveNext() method is being called repeatedly n times:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SYKYSkUU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a9e8h8axn6sl28r9fbhm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SYKYSkUU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a9e8h8axn6sl28r9fbhm.png" alt="Image description" width="720" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The MoveNext method starts by assigning the list instance into a local variable, and then validates that the enumerable struct version matches the version of the list (to verify that the list was not modified)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;((uint)_index &amp;lt; (uint)localList._size))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (_index&amp;gt;0 || _index&amp;lt;localList._size)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;worth to read about the sign bit and Two’s complement&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Two%27s_complement"&gt;https://en.wikipedia.org/wiki/Two%27s_complement&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And finally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_current = localList._items[_index];

_index++;

return true;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it assigns the next value into _current and increments the index and return true.&lt;/p&gt;

&lt;h2&gt;
  
  
  Warm up — Simple for loop
&lt;/h2&gt;

&lt;p&gt;Just for warm up, let’s start from a basic for loop, and have a look at following C# program:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3d4FZXhx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h42o3g1gp27ak2mrdjv4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3d4FZXhx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h42o3g1gp27ak2mrdjv4.png" alt="Image description" width="375" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“some code” will be executed 333 times as long there is no break, return or throw involved. However, since we are talking about iteration , we will focus on the iteration itself which is highlighted in blue and not the first initialization part.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E0F_jtl_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ifjh6t47kf45wnwv8kq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E0F_jtl_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ifjh6t47kf45wnwv8kq.png" alt="Image description" width="720" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, in any iteration, the CPU executes 11 instructions to complete each iteration that is distributed in the following way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zS7LlYzv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzlif3d2poc4sw3k80q2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zS7LlYzv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzlif3d2poc4sw3k80q2.png" alt="Image description" width="720" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Array iteration with for loop
&lt;/h2&gt;

&lt;p&gt;Now, since we are all warmed up, let’s examine how exactly .NET iterates over an array with a for loop. We will examine the next example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HSl-TGqL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6lqfqstlpmngpqzb8a8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HSl-TGqL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6lqfqstlpmngpqzb8a8.png" alt="Image description" width="549" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the disassembly:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q_JsnpHJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4vwylubf68jmzt5ib85.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q_JsnpHJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4vwylubf68jmzt5ib85.png" alt="Image description" width="720" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that iteration, the CPU will have to execute 20 instructions- each iteration is distributed in the following way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yjUahnNu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bykwm4ddot4ad34781o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yjUahnNu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bykwm4ddot4ad34781o.png" alt="Image description" width="720" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  List Iteration With a foreach loop
&lt;/h2&gt;

&lt;p&gt;Above, we saw how foreach iteration is implemented in .NET.&lt;br&gt;
Now, let’s examine the next function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OoXOuOYB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fdldir5qywh8runqy9ve.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OoXOuOYB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fdldir5qywh8runqy9ve.png" alt="Image description" width="548" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the disassembly: (as before I highlighted only the part that occur n times, and ignored the initialization)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gTdXDPuc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4r6zg1aqg0oeim8l1nkh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gTdXDPuc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4r6zg1aqg0oeim8l1nkh.png" alt="Image description" width="720" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rpQSR7a0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/np5htr1jn29otok3xvs4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rpQSR7a0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/np5htr1jn29otok3xvs4.png" alt="Image description" width="720" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s easy to see that the current iteration was much longer. The CPU executes 34 instructions, with each iteration distributed in the following way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iLqzo9m3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uj4afhr8h7qgnt79y7am.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iLqzo9m3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uj4afhr8h7qgnt79y7am.png" alt="Image description" width="720" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  List Iteration With a for loop
&lt;/h2&gt;

&lt;p&gt;Before we dig in into the assembly, there is another thing that is worth mentioning. Any time we use[] on a list instance, we are invoking the following extension:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8LvIbY5R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jz4szxuqdclu0b16j8rf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8LvIbY5R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jz4szxuqdclu0b16j8rf.png" alt="Image description" width="665" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s take the following C# function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kMb2BjpR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6vt0dh29cfet4pok692.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kMb2BjpR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6vt0dh29cfet4pok692.png" alt="Image description" width="465" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the disassembly:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VxgoTVY9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1yimbe1myql7cnpbctfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VxgoTVY9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1yimbe1myql7cnpbctfz.png" alt="Image description" width="720" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bbXENwwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn7s6xuqe59xvc4alv08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bbXENwwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn7s6xuqe59xvc4alv08.png" alt="Image description" width="720" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that iteration, the CPU executes 39 instructions n times just for the iteration which is distributed in the following way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u2oU9WnJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wc4c7i053h8vdpayhip9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u2oU9WnJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wc4c7i053h8vdpayhip9.png" alt="Image description" width="720" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Array Iteration with a foreach loop
&lt;/h2&gt;

&lt;p&gt;And for our last example let’s have a look at the following C# code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EDZsjgfw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcuelz7byx0klhqq23a1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EDZsjgfw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcuelz7byx0klhqq23a1.png" alt="Image description" width="464" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And let’s look even deeper:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u169TIbX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vhu6u2kjny9tpb03irsc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u169TIbX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vhu6u2kjny9tpb03irsc.png" alt="Image description" width="720" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that iteration, the CPU executes 16 instructions n times just for the iteration which is distributed in the following way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FGfznMw7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vh1zeee5c6lwbwsezk5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FGfznMw7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vh1zeee5c6lwbwsezk5u.png" alt="Image description" width="720" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  THE RESULTS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7cXANAC6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qtfozm51u5pmnyxs6pq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7cXANAC6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qtfozm51u5pmnyxs6pq.png" alt="Image description" width="720" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The results are displayed in the following tables: as seen in the first table above, the “total” column represents the number of assembly instructions. The“Estimated CPU cycles score” represents an estimated score that was calculated by the type of the instruction, the latency and the throughput.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Pl9TpPC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92x3ivsfqy4nxado9y6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Pl9TpPC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92x3ivsfqy4nxado9y6g.png" alt="Image description" width="445" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---dBfQGhg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dm2n5kw11zsa96mu1i6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---dBfQGhg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dm2n5kw11zsa96mu1i6v.png" alt="Image description" width="589" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To test our conclusions, &lt;a href="https://bitbucket.org/oryaacov/deep-.net/src/master/Iteration/Iteration/TimeMeasurment.cs"&gt;I created the following TimeMesurment class, And initialized it with the value of 200000000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ymdoGK24--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdhtfqp0aj2jooa42y3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ymdoGK24--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdhtfqp0aj2jooa42y3x.png" alt="Image description" width="481" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, it is nearly twice as efficient to iterate over an array then a list.&lt;/p&gt;

&lt;p&gt;Of course, that List creates a lot of necessary functionality such as adding and removing items from the collection, but sometimes developers use a List when those extra functionalities are unnecessary, as a form of a bad habit.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

&lt;p&gt;Or Yaacov&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikibooks.org/wiki/X86_Assembly/Control_Flow"&gt;https://en.wikibooks.org/wiki/X86_Assembly/Control_Flow&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://chadaustin.me/2009/02/latency-vs-throughput/"&gt;https://chadaustin.me/2009/02/latency-vs-throughput/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.cs.virginia.edu/%7Eevans/cs216/guides/x86.html"&gt;http://www.cs.virginia.edu/~evans/cs216/guides/x86.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/dotnet/core"&gt;https://github.com/dotnet/core&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/index"&gt;https://docs.microsoft.com/en-us/dotnet/csharp/index&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.agner.org/"&gt;https://www.agner.org/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>How to easily join Linux asset to AD</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Mon, 28 Aug 2023 12:19:00 +0000</pubDate>
      <link>https://dev.to/oryaacov/how-to-easily-join-linux-asset-to-ad-4l3c</link>
      <guid>https://dev.to/oryaacov/how-to-easily-join-linux-asset-to-ad-4l3c</guid>
      <description>&lt;p&gt;Syncing a Linux machine with Active Directory unlock benefits like seamless AD login, simplified asset management, and integrate your Linux machine into your company's existing environment, Here is a simple guide of how to do it :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0QnjiJ-n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6dmlkd2a140zwqztbv9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0QnjiJ-n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6dmlkd2a140zwqztbv9p.png" alt="Image description" width="604" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  RPM Based Distributions (Centos/RHEL)
&lt;/h2&gt;

&lt;p&gt;Setup dependencies&lt;br&gt;
centos7:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum install sssd realmd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools krb5-workstation openldap-clients policycoreutils-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;centos8:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum install sssd realmd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools krb5-workstation openldap-clients policycoreutils-python-utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to AD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;realm join --user=[domain user account] [domain name]
# realm join --user=myAdUser dev.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in case of error, run journalctl as described in the error, to fix KDC has no support for encryption type enable Kerberos encryption support:&lt;br&gt;
&lt;code&gt;update-crypto-policies --set DEFAULT:AD-SUPPORT&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Debian based systems (ubuntu)
&lt;/h2&gt;

&lt;p&gt;Setup dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install sssd-ad sssd-tools realmd adcli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to AD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo realm -v discover [domain name]
# sudo realm -v discover dev.com
sudo realm join --user=[domain user account] [domain name]
# realm join --user=myAdUser dev.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in case of error, run &lt;code&gt;journalctl&lt;/code&gt;as described in the error, to fix realm: Couldn't join realm: Necessary packages are not installed: sssd-tools sssd libnss-sss libpam-sss adcli even that they are installed run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;realm join --user=[domain user account] [domain name] --install=/
realm join --user=myAdUser dev.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;​&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://access.redhat.com/solutions/5728591"&gt;https://access.redhat.com/solutions/5728591&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.redhat.com/sysadmin/linux-active-directory"&gt;https://www.redhat.com/sysadmin/linux-active-directory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ubuntu.com/server/docs/service-sssd-ad"&gt;https://ubuntu.com/server/docs/service-sssd-ad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.spiceworks.com/topic/2018717-joining-debian-machine-to-ad-domain-packages-not-found"&gt;https://community.spiceworks.com/topic/2018717-joining-debian-machine-to-ad-domain-packages-not-found&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Dev.to post to markdown utility</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Fri, 19 May 2023 19:33:35 +0000</pubDate>
      <link>https://dev.to/oryaacov/devto-post-to-markdown-utility-527n</link>
      <guid>https://dev.to/oryaacov/devto-post-to-markdown-utility-527n</guid>
      <description>&lt;p&gt;Because of I love dev.to, and that I also have my own blog,&lt;br&gt;
I created a new cli that converts dev.to link to markdown :) &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NvkaN0Qy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oo9iych5d5rg5jp78du6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NvkaN0Qy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oo9iych5d5rg5jp78du6.png" alt="Image description" width="700" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How it works&lt;br&gt;
The utility extract the post id from the page, and then using the post-id to query the raw markdown from dev.to API.&lt;/p&gt;

&lt;p&gt;or you can just read the code here:&lt;br&gt;
&lt;a href="https://github.com/oryaacov/devto-to-markdown"&gt;https://github.com/oryaacov/devto-to-markdown&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Ensure you have Node.js and npm (Node Package Manager) installed on your system.&lt;/li&gt;
&lt;li&gt;Open your terminal or command prompt.&lt;/li&gt;
&lt;li&gt;Execute the following command to install the utility globally: &lt;code&gt;npm i -g devto-to-markdown&lt;/code&gt;`&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Once the utility is installed, you can convert Dev.to blogs to Markdown using the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;devto-to-markdown -u &amp;lt;devto-url&amp;gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;&amp;lt;devto-url&amp;gt;&lt;/code&gt; with the URL of the Dev.to blog you want to convert.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;devto-to-markdown -u https://dev.to/oryaacov/how-to-setup-http-server-with-security-headers-using-nginx-docker-dok&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

</description>
      <category>markdown</category>
      <category>node</category>
      <category>blog</category>
      <category>devto</category>
    </item>
    <item>
      <title>How to pass exceptions in Electron.js from main process to renderer and other way around</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Sat, 13 May 2023 10:51:21 +0000</pubDate>
      <link>https://dev.to/oryaacov/how-to-pass-exceptions-in-electronjs-from-main-process-to-rendered-and-other-way-around-1b69</link>
      <guid>https://dev.to/oryaacov/how-to-pass-exceptions-in-electronjs-from-main-process-to-rendered-and-other-way-around-1b69</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FWBm-Boj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ktjuur9ppdsqc6f8j18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FWBm-Boj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ktjuur9ppdsqc6f8j18.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you struggled as well with "bubbling" exceptions between IpcMain and IpcRenderer in electron.js here is a self-exploratory, and simple solution that I created to solve this issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {ipcMain, IpcMainInvokeEvent, ipcRenderer} from 'electron';

export interface channelMessage&amp;lt;T&amp;gt; {
  message?: T;
  error?: any;
}

export function handleMessageFromRenderer&amp;lt;T&amp;gt;(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) =&amp;gt; Promise&amp;lt;void&amp;gt; | any) {
  ipcMain.handle(channel, async (event, args) =&amp;gt; {
    const response: channelMessage&amp;lt;T&amp;gt; = {};

    try {
      response.message = await listener(event, args);
    } catch (e) {
      response.error = e;
    }

    return response;
  });
}

export async function sendMessageToMain(channel: string, ...args: any[]): Promise&amp;lt;any&amp;gt; {
  const {message, error} = await ipcRenderer.invoke(channel, ...args);
  if (error) {
    throw error;
  }

  return message;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now instead of passing a message using &lt;code&gt;ipcRenderer.invoke&lt;/code&gt; and &lt;code&gt;icpMain.handle&lt;/code&gt; you can just use &lt;code&gt;sendMessageToMain&lt;/code&gt; and &lt;code&gt;sendMessageToMain&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;as in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xport const settingChannels = {
  openLogFile: 'open-log-file',
  updateApplication: 'update-application',
};

export const settingsApi = {
  openLogFile: async () =&amp;gt; {
    await sendMessageToMain(settingChannels.openLogFile);
  },
  updateApplication: async (version) =&amp;gt; {
    await sendMessageToMain(settingChannels.updateApplication, {version});
  },
 };

export function registerSettingsApi() {
  log.debug('registering settings apis');

  handleMessageFromRenderer(settingChannels.openLogFile, async (event): Promise&amp;lt;void&amp;gt; =&amp;gt; {
    log.trace('handling open log');
    await settingsHandler.openLogFile();
  });

  handleMessageFromRenderer(settingChannels.updateApplication, async (event, args): Promise&amp;lt;void&amp;gt; =&amp;gt; {
    log.trace('handling start app update');
    await settingsHandler.updateApplication(args.version);
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>iptables rules that every Linux user should have - part one</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Mon, 17 Apr 2023 14:49:11 +0000</pubDate>
      <link>https://dev.to/oryaacov/iptables-rules-that-every-linux-user-should-have-part-one-5b6i</link>
      <guid>https://dev.to/oryaacov/iptables-rules-that-every-linux-user-should-have-part-one-5b6i</guid>
      <description>&lt;p&gt;After that I read about another cyber attack, again, as a software engineer in Zero Networks, I asked myself what the hell is going on in my network? who tries, or even worse succeeds communicating with my machine? and is my machine trying to talk to specious servers without me knowing? Well, let's create some iptables rules that will help answer those questions&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mRHPQTwd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0w8w9xrqiq216ohub4b4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mRHPQTwd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0w8w9xrqiq216ohub4b4.png" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 - Log chains
&lt;/h2&gt;

&lt;p&gt;iptables has 3 action chains, Drop, Reject, and Accept. Let's create 3 new chains, which will log any &lt;strong&gt;NEW&lt;/strong&gt; connection attempt, and then perform the wanted action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo iptables -N LOG_AND_ACCEPT
sudo iptables -A LOG_AND_ACCEPT -m conntrack --ctstate "NEW,RELATED" -j LOG --log-prefix '[OY-A]:' --log-level 7
sudo iptables -A LOG_AND_ACCEPT -j ACCEPT

sudo iptables -N LOG_AND_DROP
sudo iptables -A LOG_AND_DROP -m conntrack --ctstate "NEW,RELATED" -j LOG --log-prefix '[OY-D]:' --log-level 7
sudo iptables -A LOG_AND_DROP -j DROP

sudo iptables -N LOG_AND_REJECT
sudo iptables -A LOG_AND_REJECT -m conntrack --ctstate "NEW,RELATED" -j LOG --log-prefix '[OY-R]:' --log-level 7
sudo iptables -A LOG_AND_REJECT -j REJECT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;by running those commands, we are generating the following 3 new chains which logging (with special prefix [{two letters}-{ACTION}]):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;chain: LOG_AND_ACCEPT, log prefix: [OY-A]&lt;br&gt;
chain: LOG_AND_DROP, log prefix: [OY-D]&lt;br&gt;
chain: LOG_AND_REJECT, log prefix: [OY-R]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the log prefix will help us find our records, or even to separate our records to another file using &lt;code&gt;rsyslog&lt;/code&gt; (please let me know if you wish me to write a guide on how to do that)&lt;/p&gt;

&lt;h3&gt;
  
  
  Converting existing rules
&lt;/h3&gt;

&lt;p&gt;If you already have rules, all you need to do is to convert any existing rule target from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ACCEPT -&amp;gt; LOG_AND_ACCEPT&lt;br&gt;
DROP -&amp;gt; LOG_AND_DROP&lt;br&gt;
REJECT -&amp;gt; LOG_AND_REJECT&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2 - Inbound
&lt;/h2&gt;

&lt;p&gt;well, I'm using my system76 machine (powered by arch ❤) as a client, so I don't expect any kind of EXTERNAL INBOUND traffic at all, so let's see how to block it without affecting internal machine communication (e.g. docker containers)&lt;/p&gt;

&lt;h3&gt;
  
  
  Log and drop incoming external traffic
&lt;/h3&gt;

&lt;p&gt;before that, we will add our inbound protection rule, let's take it apart and see how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Match new inbound connections only -
&lt;em&gt;since iptables operate at the packet level, we don't wish to drop packets that are a response to our own initiated outbound communication.
e.g. we are initiating a DNS query to resolve yaacov.dev address, we do not wish to block the response to that request.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;DROP vs Reject
&lt;em&gt;both DROP and REJECT actions will prevent packets from being processed, but using REJECT will show attackers that your machine exists and refuse to accept packets. by using DROP we simply ignore the packets, and the attackers won't know that your machine exists or is "online" and will usually timeout.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Network devices
&lt;em&gt;well, lots are going on our machines, and programs such as docker are creating iptables rules to make everything work behind the scenes. Instead of dropping all of the new inbound packets, we need to drop only packets that come from our ethernet/wifi or another network device that connect us to the network. Internal loopback/docker or any other virtual interface will stay untouched.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;you can list your networks devices by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ip link show

1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wlan0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether ff:ff:ff:ff:ff:ff brd ff:ff:ff:ff:ff:ff
3: docker0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether ff:ff:ff:ff:ff:ff brd ff:ff:ff:ff:ff:ff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;since I'm using my Wifi I'll use &lt;code&gt;wlan0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, after understanding all of that let's create our first real firewall rule!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo iptables -A INPUT -m conntrack --ctstate "NEW,RELATED" -i wlan0 -j LOG_AND_DROP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;-m conntrack - ctstate "NEW,RELATED": use the conntrack module to apply this rule only on:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NEW: Represents the start of a new connection. It is typically used to track the initial packet of a new connection attempt.&lt;br&gt;
RELATED: Represents related connections, such as those associated with an existing connection. For example, FTP data connections are considered RELATED to the original FTP control connection&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;-i : networks interface (you can add multiple rules for multiple network devices)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 3 - Outbound
&lt;/h2&gt;

&lt;p&gt;so since I'm using my machine as a client and I'm over 18, I don't wish to restrict myself from imitating any kind of communication, but I surely want to know about each one of them, and make sure that my machine doesn't talk to other machines that I don't want it to talk to.&lt;/p&gt;

&lt;p&gt;we can do that by setting an outbound rule of LOG_AND_ACCEPT, this way, any new communication will be logged and we could examine it later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo iptables -A OUTPUT -m conntrack --ctstate "NEW,RELATED"  -j LOG_AND_ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4 - Persistence
&lt;/h2&gt;

&lt;p&gt;well iptables, isn't persistence, which means that after a restart all of the rules that you had will disappear. But there are a few ways to make iptables persistent. you can read about here: &lt;a href="https://yaacov.dev/#/articles/3-ways-to-make-iptables-persistent"&gt;3 ways to make iptables persistent&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 - analyze
&lt;/h2&gt;

&lt;p&gt;I will create a complete guide and share some of my own scripts about how to analyze your iptables logs and see when and with who our machine talked or tried to talk at least. (Please let me know if you wish another guide about how to analyze and personal tools)&lt;/p&gt;

</description>
      <category>iptables</category>
      <category>cybersecurity</category>
      <category>linux</category>
      <category>firewall</category>
    </item>
    <item>
      <title>How to boot from iso file using GRUB &amp; internal HDD (without external USB/CD)</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Sat, 06 Aug 2022 19:15:00 +0000</pubDate>
      <link>https://dev.to/oryaacov/how-to-boot-from-iso-file-using-grub-internal-hdd-without-external-usbcd-4a09</link>
      <guid>https://dev.to/oryaacov/how-to-boot-from-iso-file-using-grub-internal-hdd-without-external-usbcd-4a09</guid>
      <description>&lt;p&gt;I just received my new System76's Lemp11 pro, and even though I love Pop!_OS I prefer to use Arch (btw), but… I didn't have an external USB drive that will use me as installation media, so…&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Partition
&lt;/h2&gt;

&lt;p&gt;I have two internal hard drives and I'm going to shrink my secondary one to allocate more space for a new partition, you can skip this step in case you have some available memory.&lt;/p&gt;

&lt;p&gt;Open Disks, and resize your partition&lt;br&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%2Fm7dqq2ftpdlh1aqgfft8.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%2Fm7dqq2ftpdlh1aqgfft8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I Choose to leave 32GB my internal partition&lt;/p&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%2F58moc7zysj9ccsv0pyb5.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%2F58moc7zysj9ccsv0pyb5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;in the free space create a new &lt;code&gt;ext4&lt;/code&gt; and name it as you want :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Copying the ISO files
&lt;/h2&gt;

&lt;p&gt;step one, copy the iso files to the new disk that you just created. &lt;br&gt;
step two, None.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing the data
&lt;/h2&gt;

&lt;p&gt;in the next and last step, we will need to configure our grub, and for this, we will need to collect a few pieces of data:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;your .iso file hdd number:
you can run &lt;code&gt;lsblk | grep disk&lt;/code&gt; to list your hard drives:&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;/dev/hda&lt;/code&gt; refers to the first IDE hard drive&lt;br&gt;
&lt;code&gt;/dev/sda&lt;/code&gt; refers to the first SCSI or SATA hard drive.&lt;br&gt;
 If you use a NMVe SSD, it might be named as &lt;code&gt;/dev/nvme0n1&lt;/code&gt;, &lt;code&gt;/dev/nvme1n1&lt;/code&gt; and so on.&lt;br&gt;
But in GRUB, the first hard drive is always referred to as hd0, no matter what the interface type is&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;your .iso file partition number:&lt;br&gt;
you can run the following command &lt;code&gt;sudo parted -l&lt;/code&gt;  and locate your iso's files partition number&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;your setup's .efi files&lt;br&gt;
browse trough your .iso files (you can do it by mount your iso or open it an archive manager), and locate your desired linuz .efi file and image file&lt;br&gt;
for example:&lt;br&gt;
Ubuntu setup: &lt;br&gt;
 &lt;code&gt;/casper/vmlinuz&lt;/code&gt; and &lt;code&gt;/casper/initrd&lt;/code&gt;&lt;br&gt;
Arch setup&lt;br&gt;
&lt;code&gt;/arch/boot/x86_64/vmlinuz-linux&lt;/code&gt; and &lt;code&gt;/arch/boot/x86_64/initramfs-linux&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Configuring GRUB
&lt;/h2&gt;

&lt;p&gt;use your favorite text editor to add the following line to &lt;/p&gt;

&lt;p&gt;your custom configuration file:&lt;br&gt;
&lt;code&gt;sudo vi /etc/grub.d/40_custom&lt;/code&gt; &lt;br&gt;
(if the file doesn't exists &lt;code&gt;/etc/grub.d/40_custom&lt;/code&gt; and &lt;br&gt;
update-grub executable install, please install grub-disk)&lt;/p&gt;

&lt;p&gt;and add the following lines:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

menuentry "{{menu entry name}}" {
  insmod ext2
  set isopartition=hd{{hdd number}},{{partition number}}
  set isofile="{{iso file path (relative to hdd)}}"
  loopback loop (hd{{hdd number}},{{partition number}})$isofile
  linux (loop){{iso's vm linuz efi file path}} img_dev=/dev/disk/by-uuid/$isouuid img_loop=$isofile
  initrd (loop){{iso's ram memory image file path}}
}


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

&lt;/div&gt;

&lt;p&gt;working example (Arch linux)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

menuentry "archlinux-2022.07.01-x86_64.iso" {
  insmod ext2
  set isopartition=hd1,2
  set isofile="/iso/archlinux-2022.07.01-x86_64.iso"
  loopback loop (hd1,2)$isofile
  linux (loop)/arch/boot/x86_64/vmlinuz-linux img_dev=/dev/disk/by-uuid/$isouuid img_loop=$isofile
  initrd (loop)/arch/boot/x86_64/initramfs-linux.img
}


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

&lt;/div&gt;

&lt;p&gt;Ubuntu:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

menuentry "ubuntu-20.04.2.0-desktop-amd64.iso" {
  insmod ext2
  set isofile="/iso/ubuntu-20.04.2.0-desktop-amd64.iso"
  loopback loop (hd1,2)$isofile
  linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$isofile quiet noeject noprompt splash
  initrd (loop)/casper/initrd
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;menuentry:&lt;/strong&gt; your GRUB2 menu entry, name it as you like.&lt;br&gt;
&lt;strong&gt;insmod:&lt;/strong&gt; inserts a module. Since the ISO file is stored in ext4 partition he ext2 module is needed.&lt;br&gt;
&lt;strong&gt;set isofile&lt;/strong&gt;: Specify that path of your ISO image file&lt;br&gt;
&lt;strong&gt;loopback:&lt;/strong&gt; Mount the ISO file. hd0 means the first hard drive in the computer and 5 means the ISO file is stored on the 5th disk partition.&lt;br&gt;
The linux command loads a Linux kernel from the specified path. casper/vmlinuz.efi is the linux kernel inside the Ubuntu ISO image.&lt;br&gt;
&lt;strong&gt;initrd&lt;/strong&gt;: initrd command loads an initial ramdisk from the specified path. It can only be used after the linux command has been run. The initial ramdisk is a minimal root file system mounted to the RAM. casper/initrd.lz is the initrd file inside the Ubuntu ISO image.&lt;/p&gt;

&lt;p&gt;next all you need to do is to run the following command &lt;code&gt;sudo update-grub&lt;/code&gt; and reboot. &lt;/p&gt;

&lt;p&gt;All done :)&lt;/p&gt;

</description>
      <category>linux</category>
      <category>grub</category>
      <category>iso</category>
      <category>boot</category>
    </item>
    <item>
      <title>Healthy snacks ideas? (office)</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Tue, 10 May 2022 13:33:10 +0000</pubDate>
      <link>https://dev.to/oryaacov/healthy-snacks-ideas-office-94h</link>
      <guid>https://dev.to/oryaacov/healthy-snacks-ideas-office-94h</guid>
      <description>&lt;p&gt;I'm looking to find some healthy snacks idea for the office.&lt;/p&gt;

&lt;p&gt;All of the healthy 0-guilt food that I have by now is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Baby cucumber &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Baby carrots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sparkling water &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Help please :)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i69oB0Ir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8ebxl5fspm57kudc371.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i69oB0Ir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8ebxl5fspm57kudc371.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Don't abuse critical sections</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Sat, 07 May 2022 17:30:03 +0000</pubDate>
      <link>https://dev.to/oryaacov/dont-abuse-critical-sections-26fc</link>
      <guid>https://dev.to/oryaacov/dont-abuse-critical-sections-26fc</guid>
      <description>&lt;p&gt;Critical section is a code block that cannot be executed by more than one process/thread at a time, which is why critical sections are expensive and can lead to a performance "bottle neck" at a specific flow. &lt;/p&gt;

&lt;p&gt;Critical sections must be as short, simple (if possible), and efficient as possible. &lt;/p&gt;

&lt;p&gt;For example, let's examine the following code block, which  generates a new UUID for a shared object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;with self._mutex:
    # start of lock 
    try:
        self._action.id = str(uuid.uuid4())                      
        self._logger.trace("action generated, action_id={action_id}".format(action_id=self._action.id))
    except BaseException as err:
        self._logger.error(err,"failed to generate uuid")
    # end of lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I did three common mistakes here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;try &amp;amp; catch, ok, I admit it, probably not a common mistake since no one will put a try &amp;amp; catch that could be outside of a critical section inside of it without a good reason&lt;/li&gt;
&lt;li&gt;logging inside a critical section. Usually, logging is an expensive IO operation which could have be done outside&lt;/li&gt;
&lt;li&gt;generating the UUID inside the critical section&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the another code block which does the exact same thing, just without the three mistakes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try:
    action_id = str(uuid.uuid4())
    with self._mutex:
        # start of lock
        self._action.id = action_id                  
        # end of lock

    self._logger.trace("action generated, action_id={action_id}".format(id=action_id))  
except BaseException as err:
    self._logger.error(err,"failed to generate uuid")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you are using lock remember that is purpose is to avoid more than one thread access shared resources at the same time&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>3 ways to make iptables persistent</title>
      <dc:creator>Or Yaacov</dc:creator>
      <pubDate>Sat, 23 Apr 2022 15:32:08 +0000</pubDate>
      <link>https://dev.to/oryaacov/3-ways-to-make-iptables-persistent-4pp</link>
      <guid>https://dev.to/oryaacov/3-ways-to-make-iptables-persistent-4pp</guid>
      <description>&lt;p&gt;If you are using iptables, it's very likely that you wish to make it persistent, and restore your firewall rules after a reboot.&lt;/p&gt;

&lt;p&gt;I'll present here 3 ways to make your iptables persistent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;using &lt;code&gt;systemd&lt;/code&gt;,my personal favorite way, since it works for all Linux distributions and without requiring 3rd party software.&lt;/li&gt;
&lt;li&gt;using &lt;code&gt;iptables-persistent&lt;/code&gt; mostly for DEB-based Linux distributions, required 3rd party software&lt;/li&gt;
&lt;li&gt;using &lt;code&gt;iptables-services&lt;/code&gt; for RPM-based Linux distributions, required 3rd party software&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  systemd
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;systemd&lt;/code&gt; is a system and service manager for Linux operating systems. Using &lt;code&gt;systemd&lt;/code&gt; we can run a script file after boot, that will restore our firewall rules and make it persistent without installing a 3rd party software.&lt;br&gt;
first let's create the script that we wish to run to restore our firewall:&lt;br&gt;
&lt;code&gt;sudo vi /etc/iptables-persistent/restore.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;with the following script:&lt;br&gt;
&lt;code&gt;#!/bin/sh&lt;br&gt;
/usr/bin/flock /run/.iptables-restore /sbin/iptables-restore &amp;lt; {{your ip tables dump file}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;next we will need to create an host file for our &lt;code&gt;systemd&lt;/code&gt; service using: &lt;br&gt;
&lt;code&gt;sudo vi /etc/systemd/system/iptables-persistent.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and paste the following &lt;br&gt;
&lt;code&gt;[Unit] &lt;br&gt;
Description=iptables persistent service&lt;br&gt;
ConditionFileIsExecutable=/etc/iptables/restore-iptables.sh&lt;br&gt;
After=network.target&lt;br&gt;
[Service]&lt;br&gt;
Type=forking&lt;br&gt;
ExecStart=/etc/iptables/restore-iptables.sh&lt;br&gt;
start TimeoutSec=0&lt;br&gt;
RemainAfterExit=yes&lt;br&gt;
GuessMainPID=no&lt;br&gt;
[Install]&lt;br&gt;
WantedBy=multi-user.target&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;great, now all that is left to do is simply enable our service by running the following command:&lt;br&gt;
&lt;code&gt;sudo systemctl enable iptables-persistent.service&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  iptables-persistent (DEB)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;iptables-persistent&lt;/code&gt; automatically loads your saved ip-tables rules after a reboot.&lt;br&gt;
First step will be to install &lt;code&gt;iptables-persistent&lt;/code&gt; using &lt;code&gt;sudo apt-get install iptables-persistent&lt;/code&gt;&lt;br&gt;
since &lt;code&gt;iptables-persistant&lt;/code&gt; will look for two dump files:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;/etc/iptables/rules.v4 #for ipv4 rules&lt;br&gt;
/etc/iptables/rules.v6 #for, wait for it, ipv6 rules&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;which you can easily create running the following commands:&lt;br&gt;
&lt;code&gt;sudo iptables-save &amp;gt; /etc/iptables/rules.v4&lt;/code&gt;&lt;br&gt;
&lt;code&gt;sudo ip6tables-save &amp;gt; /etc/iptables/rules.v6&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Depends on your OS version, behind the scenes &lt;code&gt;iptables-persistent&lt;/code&gt; works with &lt;code&gt;netfilter-persistent.service&lt;/code&gt; you can verify that your service up and running using &lt;code&gt;sudo systemctl status netfilter-persistent.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and your output should look like the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;netfilter-persistent.service - netfilter persistent &lt;br&gt;
configuration&lt;br&gt;
 Loaded: loaded (/lib/systemd/system/netfilter-persistent.service; enabled; ve&lt;br&gt;
 Active: active (exited) since Sat 2022–04–09 18:14:42 IDT; 29min ago&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  iptables-services (RPM)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;iptables-services&lt;/code&gt; contains a persistent utility that loads your saved ip-tables rules after a reboot.&lt;br&gt;
Let's start with installing &lt;code&gt;iptables-services&lt;/code&gt; using &lt;code&gt;sudo dnf install iptables-services&lt;/code&gt;&lt;br&gt;
after installing &lt;code&gt;iptables-services&lt;/code&gt; we will need to make sure that our service is up and that firewalld is disabled and won't interfere with our iptables configuration, using the following commands:&lt;br&gt;
 &lt;code&gt;sudo systemctl stop firewalld&lt;br&gt;
 sudo systemctl disable firewalld&lt;br&gt;
 sudo systemctl start iptables&lt;br&gt;
 sudo systemctl enable iptables&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;since iptables-services will look for two dump files:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;/etc/sysconfig/iptables #for ipv4 rules&lt;br&gt;
/etc/sysconfig/ip6tables #for, wait for it, ipv6 rules&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;which you can easily create running the following commands:&lt;br&gt;
&lt;code&gt;sudo iptables-save &amp;gt; /etc/iptables/rules.v4&lt;br&gt;
 sudo ip6tables-save &amp;gt; /etc/iptables/rules.v6&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and that's it, you can feel free to reboot your machine without losing your changes :)&lt;/p&gt;

</description>
      <category>iptables</category>
      <category>linux</category>
      <category>firewall</category>
      <category>security</category>
    </item>
  </channel>
</rss>
