<?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: Mohammed Al Ashaal</title>
    <description>The latest articles on Forem by Mohammed Al Ashaal (@alash3al).</description>
    <link>https://forem.com/alash3al</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%2F304482%2Faf3b1830-2c43-43bd-8980-e3b587d7a4c7.jpeg</url>
      <title>Forem: Mohammed Al Ashaal</title>
      <link>https://forem.com/alash3al</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alash3al"/>
    <language>en</language>
    <item>
      <title>Back to php-fpm, unpopular opinion</title>
      <dc:creator>Mohammed Al Ashaal</dc:creator>
      <pubDate>Fri, 11 Aug 2023 13:16:05 +0000</pubDate>
      <link>https://forem.com/alash3al/php-back-to-fpm-unpopular-opinion-4lg5</link>
      <guid>https://forem.com/alash3al/php-back-to-fpm-unpopular-opinion-4lg5</guid>
      <description>&lt;p&gt;Everyday there are a lot of trendy technologies and tools out there, when it comes to PHP the trendy concept is "Async PHP" where there are some packages/extensions tells us that it provides a truly &lt;strong&gt;async&lt;/strong&gt; functionality but in php, that is right, but there is something more important we didn't answer, which is "What is the actual problem we're trying to solve here?".&lt;/p&gt;

&lt;p&gt;You're trying to solve performance issues by re-inventing the wheel, PHP-FPM has already been built years ago to provide a FastCGI process manager that manage PHP processes and gives you a lot of scalability options, you can easily scale it to handle multiple requests at a time by configuring how many processes you want to be available, which we can map it to "workers", it also enables you to configure the maximum time a worker takes to finish a request, if it exceeded that time, it would be terminated instantly!, as well a lot of security problems it solves.&lt;/p&gt;

&lt;p&gt;If your request life cycle is designed to take 1 second, then it will take 1 second, it isn't a language only problem it is about how you're writing the control flows, database queries, external network calls, ... etc.&lt;/p&gt;

&lt;p&gt;Just try to write a "Hello World" in both PHP and nodejs without any framework, you will find that the're very close to each other, this post isn't about benchmarking but it is about PHP-FPM only.&lt;/p&gt;

&lt;p&gt;All new tools claims the async world, already do the above mentioned concepts already but in another way which doesn't solve the main problem "the community and the ecosystem" which isn't a problem at all!&lt;/p&gt;

&lt;p&gt;But you may find another problem which is "simplcify" how to simplify the production runtime, I don't want to write a nginx.conf, php-fpm.ini and php.ini in addition to my original application configurations, I'll say, "You're right", that's why there are many tools out there to do so instead of you, something like &lt;a href="https://github.com/alash3al/phoo"&gt;PHOO&lt;/a&gt; which is being used and tested in production, is doing a lot of magic for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configures, spawns and control the PHP-FPM process transparently for you.&lt;/li&gt;
&lt;li&gt;Offloads the HTTP requests and proxies them to the FastCGI workers handled by the FPM process.&lt;/li&gt;
&lt;li&gt;Serves static files for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All what you need is &lt;code&gt;phoo serve -r ./public&lt;/code&gt; to serve your laravel project without any extra lines of configurations.&lt;/p&gt;

&lt;p&gt;Let's back to basics, any old stuff isn't build for old days, but it is proven to work over years/decades, so let's make use of the old but gold tools.&lt;/p&gt;

&lt;p&gt;The above words are just my personal opinion which doesn't mean "PHP is the best" but it means that each tool is designed to do somethings better than others, and thinking about the main problem you're trying to solve is the main problem you should focus on, as not all the apps/websites out there focuses on 1ms response time only! that's why the productive frameworks exist, if you need raw performance go and write everything from scratch.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introduction to scrapy-x</title>
      <dc:creator>Mohammed Al Ashaal</dc:creator>
      <pubDate>Thu, 24 Dec 2020 06:59:19 +0000</pubDate>
      <link>https://forem.com/alash3al/introduction-to-scrapy-x-311a</link>
      <guid>https://forem.com/alash3al/introduction-to-scrapy-x-311a</guid>
      <description>&lt;p&gt;Today I'm introducing a piece of code that I worked on in my enjoyment time, it is called scrapyx or X.&lt;/p&gt;

&lt;p&gt;Simply it is a scrapy module (subcommand) that creates a fastapi based server to enable you to control scrapy as you want.&lt;/p&gt;

&lt;p&gt;It is a very simple library that uses redis as a persistent queue.&lt;/p&gt;

&lt;p&gt;It is fully configurable via the settings.py file of your scrapy project.&lt;/p&gt;

&lt;p&gt;you can find it &lt;a href="https://github.com/alash3al/scrapy-x"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you found it useful, just start it on github ♥️&lt;/p&gt;

</description>
      <category>scrapy</category>
      <category>python</category>
      <category>crawling</category>
    </item>
    <item>
      <title>using jQuery-like syntax to scrap websites</title>
      <dc:creator>Mohammed Al Ashaal</dc:creator>
      <pubDate>Fri, 14 Aug 2020 10:57:09 +0000</pubDate>
      <link>https://forem.com/alash3al/using-jquery-like-syntax-to-scrap-websites-db8</link>
      <guid>https://forem.com/alash3al/using-jquery-like-syntax-to-scrap-websites-db8</guid>
      <description>&lt;p&gt;Without introduction, let's play with a simple tool that may help you scraping any HTML content easily and building a JSON based API from it.&lt;/p&gt;

&lt;p&gt;Our tool is called &lt;code&gt;Scraply&lt;/code&gt;, it is developed in &lt;code&gt;Golang&lt;/code&gt;, and utilizes &lt;code&gt;HCL&lt;/code&gt; and &lt;code&gt;Javascript&lt;/code&gt; to simplify the configurations and scraping process.&lt;/p&gt;

&lt;p&gt;Each scraping operation is called &lt;code&gt;macro&lt;/code&gt;, a macro is just a simple configuration to scrap a specific URL, let's see an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;macro&lt;/span&gt; &lt;span class="nx"&gt;sqler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/alash3al/sqler"&lt;/span&gt;
    &lt;span class="nx"&gt;ttl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;
    &lt;span class="nx"&gt;exec&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;JS&lt;/span&gt;&lt;span class="sh"&gt;
        exports = {
            title: $('title').Text(),
            description: $('meta[name="description"]').AttrOr('content', '')
        }
&lt;/span&gt;&lt;span class="no"&gt;    JS
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the above example, we defined a macro called &lt;code&gt;sqler&lt;/code&gt; and set the URL of the page we want to scrap its info, as well as a TTL in seconds (for caching purposes) and the execution code.&lt;/p&gt;

&lt;p&gt;Let's say that we saved the above content in a file named &lt;code&gt;test.scraply.hcl&lt;/code&gt;, now we can start the scraply engine by running the following command where we saved the file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;/path/to/scraply_bin 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;if you want to dig more into the tool and read more about it, just go to its repo from &lt;a href="https://github.com/alash3al/scraply"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>scraping</category>
      <category>jquery</category>
      <category>javascript</category>
      <category>go</category>
    </item>
    <item>
      <title>sending SQL results periodically to slack</title>
      <dc:creator>Mohammed Al Ashaal</dc:creator>
      <pubDate>Sun, 28 Jun 2020 20:41:29 +0000</pubDate>
      <link>https://forem.com/alash3al/sending-sql-results-periodically-to-slack-cgk</link>
      <guid>https://forem.com/alash3al/sending-sql-results-periodically-to-slack-cgk</guid>
      <description>&lt;p&gt;Sometimes we want to notify ourselves or our teammates about an important update based on our business database(s) without a large setup, so we start searching about a very small tool that does the required job with no hassle, as well we want it to be flexible so we can customize the final message and send it to slack easily.&lt;/p&gt;

&lt;p&gt;Today I'm happy to introduce &lt;code&gt;sql2slack&lt;/code&gt;, it is a very tiny and portable software that just does the job, it allows you to define your SQL query as a job to be executed at a configured schedule as well it works with the major databases out there.&lt;/p&gt;

&lt;p&gt;At first, we need to get a slack webhook url,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go &lt;a href="https://api.slack.com/apps"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click on &lt;code&gt;Create New App&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;Incoming Webhooks&lt;/code&gt; and activate it.&lt;/li&gt;
&lt;li&gt;Scroll down to &lt;code&gt;Add New Webhook to Workspace&lt;/code&gt; and follow the instructions.&lt;/li&gt;
&lt;li&gt;Scroll down to the webhooks table, and copy the generated webhook URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's see how we can send the newly registered (within the last 2 hours) users in our MySQL database to a slack channel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;job&lt;/span&gt; &lt;span class="nx"&gt;new_users&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// set the slack webhook url here&lt;/span&gt;
    &lt;span class="nx"&gt;channel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://service.slack.com/xxxxxxx"&lt;/span&gt;

    &lt;span class="c1"&gt;// we're using mysql&lt;/span&gt;
    &lt;span class="nx"&gt;driver&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mysql"&lt;/span&gt;

    &lt;span class="c1"&gt;// the connection string&lt;/span&gt;
    &lt;span class="nx"&gt;dsn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"root:root@tcp(127.0.0.1:3306)/dbname"&lt;/span&gt;

    &lt;span class="c1"&gt;// define the sql query here!&lt;/span&gt;
    &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;SQL&lt;/span&gt;&lt;span class="sh"&gt;
        SELECT users.* FROM users where created_at &amp;gt; DATE_SUB(NOW(),INTERVAL 2 HOUR); 
&lt;/span&gt;&lt;span class="no"&gt;    SQL

&lt;/span&gt;    &lt;span class="c1"&gt;// schedule it each 2 hours&lt;/span&gt;
    &lt;span class="nx"&gt;schedule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"* */2 * * *"&lt;/span&gt;

    &lt;span class="c1"&gt;// here we recieve the rows from the above query and pass the message to slack with each user name.&lt;/span&gt;
    &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;JS&lt;/span&gt;&lt;span class="sh"&gt;
        if ( $rows.length &amp;lt; 1 ) {
            return
        }

        say("there are (", $rows.length, ") new users!")
        say("users list is:")

        _.chain($rows).pluck('name').each(function(name){
            say("- ", name, " .")
        })
&lt;/span&gt;&lt;span class="no"&gt;    JS
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To learn more about &lt;code&gt;sql2slack&lt;/code&gt;, you can go to its &lt;a href="https://github.com/alash3al/sql2slack"&gt;github repo&lt;/a&gt;, and don't forget to star it.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>slack</category>
      <category>go</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
