<?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: Thomas Cross</title>
    <description>The latest articles on DEV Community by Thomas Cross (@chmoder).</description>
    <link>https://dev.to/chmoder</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%2F414786%2Fd122cda6-ae4f-4aa3-866b-448a0816967d.jpg</url>
      <title>DEV Community: Thomas Cross</title>
      <link>https://dev.to/chmoder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chmoder"/>
    <language>en</language>
    <item>
      <title>Is GCP internal network slower than AWS?</title>
      <dc:creator>Thomas Cross</dc:creator>
      <pubDate>Fri, 25 Sep 2020 13:18:28 +0000</pubDate>
      <link>https://dev.to/chmoder/is-gcp-internal-network-slower-than-aws-e7g</link>
      <guid>https://dev.to/chmoder/is-gcp-internal-network-slower-than-aws-e7g</guid>
      <description>&lt;p&gt;I am working on a side project that intends to provide tracking of application performance at the function level called &lt;a href="https://criterion.dev"&gt;Criterion.dev&lt;/a&gt;.  The Criterion API uses a PostgreSQL database and Actix Web for the web service.&lt;/p&gt;

&lt;p&gt;I am very happy with the performance, but still, some random thought came to mind that made me question the numbers.&lt;/p&gt;

&lt;h4&gt;
  
  
  GCP Infrastructure
&lt;/h4&gt;

&lt;p&gt;Compute Engine: E2-small&lt;br&gt;
Cloud SQL: PostgreSQL 1v shared CPU .6GB&lt;br&gt;
API request wait time: 84ms&lt;/p&gt;

&lt;h4&gt;
  
  
  AWS Infrastructure
&lt;/h4&gt;

&lt;p&gt;EC2: t2.micro&lt;br&gt;
RDS: db.t2.micro&lt;br&gt;
API request wait time: 42ms&lt;/p&gt;

&lt;p&gt;I started the service on GCP, so I logged into that instance and then into the SQL server and ran some queries by hand.  The same queries that the service executes &lt;strong&gt;actually take less than 2ms&lt;/strong&gt;.  This convinced me that the network was the bulk of the request wait time.&lt;/p&gt;

&lt;p&gt;So I copied my project over to AWS made a new subdomain and connected the SPA to it - The request time was 40ms less.  &lt;/p&gt;

&lt;p&gt;Have you ever seen this before?  Could it be due to the shared/free instance tiers I am experimenting with?  &lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>aws</category>
      <category>postgres</category>
      <category>rust</category>
    </item>
    <item>
      <title>How to choose a language on Google App Engine if performance matters</title>
      <dc:creator>Thomas Cross</dc:creator>
      <pubDate>Fri, 26 Jun 2020 18:03:03 +0000</pubDate>
      <link>https://dev.to/chmoder/how-to-choose-a-language-on-google-app-engine-if-performance-matters-2k3</link>
      <guid>https://dev.to/chmoder/how-to-choose-a-language-on-google-app-engine-if-performance-matters-2k3</guid>
      <description>&lt;p&gt;So you may know one programming language really well, you are a polyglot, or you may be learning your first right now.  Kudos to you no matter which camp you are in!&lt;/p&gt;

&lt;p&gt;This post is going to focus on &lt;a href="https://cloud.google.com/appengine/docs/standard/runtimes"&gt;app engine standard second generation&lt;/a&gt; in particular, and the languages I would personally consider for my projects.  There are a few more that I could add to this post, just comment on this and let me know if that interests you and I can add them - more on that later.&lt;/p&gt;

&lt;p&gt;These graphs are centered around Django 3 - this framework is very popular but it may not be the best framework for you if performance is a priority.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tGD6t2i6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/sLtDIH6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tGD6t2i6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/sLtDIH6.png" alt="build-start-request-times" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;build time&lt;/strong&gt; - the time it takes to build a docker image with cloud build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;start up time&lt;/strong&gt; - the time it takes for a server to start and accept requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;request time&lt;/strong&gt; - the time it takes for the framework to respond to a "hello world" request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Request time&lt;/strong&gt; is important because you can kind of place a constant K value on the time it takes to process a request; possibly even apply some time factor to every request.  &lt;strong&gt;Start up time&lt;/strong&gt; is important because it is the time a client will have to wait if there is no server available to process the request.  For this reason, if your app has a large influx of traffic, I suggest choosing a framework with low start up times.  &lt;strong&gt;Build time&lt;/strong&gt; is more of an awareness statistic - a nice to know.   CI/CD processes become concerned with this, but unit and integration tests and other processes tend to take longer than build time.&lt;/p&gt;

&lt;p&gt;Here is the data shown without build time as a consideration&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YYamsb9N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/sZyGp7O.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YYamsb9N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/sZyGp7O.png" alt="build-start-request-times" width="800" height="493"&gt;&lt;/a&gt;&lt;br&gt;
This graph makes it pretty easy to pick a framework because you can weigh the relative start and request times.  I wish there was something Google could do for Java/Spring, that start up time inhibits scaling abilities quite a bit.&lt;/p&gt;

&lt;p&gt;I am curious how Laravel and Express fit in.  Let me know if you are as well and I will update this blog with those added to the charts!&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>go</category>
      <category>django</category>
      <category>java</category>
    </item>
    <item>
      <title>Scale to 1000 concurrent users on a raspberry pi 4</title>
      <dc:creator>Thomas Cross</dc:creator>
      <pubDate>Thu, 25 Jun 2020 04:08:36 +0000</pubDate>
      <link>https://dev.to/chmoder/scale-to-1000-concurrent-users-on-a-raspberry-pi-4-4gne</link>
      <guid>https://dev.to/chmoder/scale-to-1000-concurrent-users-on-a-raspberry-pi-4-4gne</guid>
      <description>&lt;p&gt;I have been investigating rust web frameworks and have to say this one is my favorite.  Not just because of its performance, but the features, design choice, and ecosystem.&lt;/p&gt;

&lt;p&gt;Actix web is a web framework that uses the &lt;a href="https://en.wikipedia.org/wiki/Actor_model"&gt;actor model&lt;/a&gt; to perform HTTP requests.  It has middlewares, SSL, HTTP/2, and many "extras".&lt;/p&gt;

&lt;p&gt;My main reason for looking into this is because I think Rust can facilitate a future of fast, safe, concurrent software.  Coming from php, python, Java, ... the barrier to learning was really to learn Rust(a non object oriented language).  I've always wanted to write bare metal web services, but would prefer not to use C++ because of the mistakes we can make.&lt;/p&gt;

&lt;p&gt;The results impressed me so much that I decided to publish them here and provide the &lt;a href="https://github.com/chmoder/rust-practice-actix-web"&gt;source code&lt;/a&gt; for you as a sort of kicking off point.&lt;/p&gt;

&lt;p&gt;This test is a lot like &lt;a href="https://dev.to/chmoder/my-first-rust-web-service-and-other-firsts-3mhi"&gt;my other one&lt;/a&gt; except the redis pool is async via &lt;a href="https://crates.io/crates/deadpool-redis"&gt;deadpool&lt;/a&gt; and obviously actix.&lt;/p&gt;

&lt;p&gt;All this service does is use a thread pool in the HTTP handler to get a value from redis and print out some &lt;em&gt;hello world&lt;/em&gt; type message.  This implementation is more than a 10X improvement in concurrency and 2X in latency compared to the aforementioned warp test.  In fact, I noticed redis may have been slowing the benchmark down because it needed so much CPU.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tcross@spongebob:~$ siege -c1000 -r 50 -H  'Content-Type: application/json' 'http://192.168.1.2:8080/tcross/1/index.html'
** SIEGE 4.0.4
** Preparing 1000 concurrent users for battle.
The server is now under siege...
Transactions:              50000 hits
Availability:             100.00 %
Elapsed time:              26.41 secs
Data transferred:           6.68 MB
Response time:              0.52 secs
Transaction rate:        1893.22 trans/sec
Throughput:             0.25 MB/sec
Concurrency:              990.76
Successful transactions:       50000
Failed transactions:               0
Longest transaction:            1.66
Shortest transaction:           0.00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you enjoyed reading this, find me on any channel and ask questions!  &lt;a href="https://github.com/chmoder/rust-practice-actix-web"&gt;Here is the source&lt;/a&gt;!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My First Rust Web Service (And Other Firsts)</title>
      <dc:creator>Thomas Cross</dc:creator>
      <pubDate>Thu, 25 Jun 2020 00:03:30 +0000</pubDate>
      <link>https://dev.to/chmoder/my-first-rust-web-service-and-other-firsts-3mhi</link>
      <guid>https://dev.to/chmoder/my-first-rust-web-service-and-other-firsts-3mhi</guid>
      <description>&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Many Firsts&lt;/li&gt;
&lt;li&gt;Rust is Different&lt;/li&gt;
&lt;li&gt;Warp&lt;/li&gt;
&lt;li&gt;Raspberry PI 4 Benchmark&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Many Firsts &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This blog post is many firsts for me. My first blog post, first post on medium, first time I compiled Rust code on a raspberry pi, first time I benchmarked a web service on raspberry pi, … there is probably even more. So please give me feedback on how I can improve my writing for you!&lt;/p&gt;

&lt;p&gt;I realized that a large community of people exist that desire to learn the things I am learning but struggle to break into the technical space. So my goal for my writing is to lower that barrier by providing my experience, source code, and even directly helping over whatever channels work best. Feel free to ask questions here, or twitter, or anything. I hope that you can take my projects and build upon them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rust is Different &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;According to the stack overflow developer survey, Rust has been the most loved language since 2016 (over 4 years today). I have been keeping an eye on the language for some time now, and feel like it is finally in a place I would consider it stable — not mature necessarily — but stable. Stable in the sense that the syntax and community are developed. So after watching many YouTube videos, reading articles, and even testing out various projects I decided to invest more time into the rust ecosystem and I have to admit, it is nice.&lt;/p&gt;

&lt;p&gt;For your benefit I should note that my primarily used languages are Python, C, C++, and Java; with python being my most familiar. Admittedly, Rust feels very different to me and I am still learning the fundamentals. I can not say I love the syntax. Rust does not have OOP design paradigms, and surprisingly passing variables was tough to get used to because of the borrow checker.&lt;/p&gt;

&lt;p&gt;However, I can say I love the compiler, which uses LLVM as its back end and has clear messaging to explain what is wrong. Rust comes with amazing tools out of the box; such as automatic documentation generator, linter, code formatter, package manager, …. It even has the ability to write tests in the doc strings, and run them without third party libs.&lt;/p&gt;

&lt;p&gt;I am in the process of learning rust by completing the rustlings courses. But I am also a hands on learner — hence this experiment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warp &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A super-easy, composable, web server framework for warp speeds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I found this web server framework different than others I have used in the past, and I will try a couple more soon. Regardless, I am glad I tried warp, they are on to something with this feature they call “filters”. It allows your routes to be built with a builder pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"register"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;.and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redis_pool&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;.and_then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code sample makes a route and registers it to a function called “register” that may be accessed in the following way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP
POST /register HTTP/1.1
Host: 192.168.1.2:3030
{
    "username": "chmoder",
    "password": "password"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The neat takeaway for me here is that you compose what will catch a route and prepare the data for the function that intercepts the request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Raspberry PI 4 Benchmark &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;High level talk: This service has two routes “register” and “login”. Register saves a user and password-hash to redis. Login gets the password for the username. This is totally contrived and doesn’t make sense as an application. But it does allow us to see what kind performance we can get from warp with a real-world database.&lt;/p&gt;

&lt;p&gt;In this project you will find &lt;strong&gt;main.rs&lt;/strong&gt;, and &lt;strong&gt;main-mutex.rs&lt;/strong&gt;. main-mutex was my first iteration. It used a mutex to share a redis connection among the warp threads. Main.rs gives each handler a r2d2 connection pool for redis. This allowed me to remove a few things from the code and get &amp;gt; 2X performance.&lt;/p&gt;

&lt;p&gt;By the way the server was compiled and ran on a raspberry pi 4 and used only 23 Mb of memory.&lt;/p&gt;

&lt;h4&gt;
  
  
  main-mutex.rs
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;siege -c100 -r 10 -H  'Content-Type: application/json' 'http://192.168.1.2:3030/login POST { "username": "chmoder","password": "password"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mutex version is not completely utilizing the CPU because only has one process is in “running” state at any given time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EV9at1Gf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/DLneVBm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EV9at1Gf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/DLneVBm.png" alt="Main Mutex htop" width="700" height="247"&gt;&lt;/a&gt;&lt;br&gt;
Our concurrency looks good but some transactions had to wait &lt;br&gt;
8.4 seconds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;** SIEGE 4.0.4
** Preparing 100 concurrent users for battle.
The server is now under siege...
Transactions:             1000 hits
Availability:             100.00 %
Elapsed time:             37.55 secs
Data transferred:         0.00 MB
Response time:            3.48 secs
Transaction rate:         26.63 trans/sec
Throughput:               0.00 MB/sec
Concurrency:              92.55
Successful transactions:  1000
Failed transactions:      0
Longest transaction:      8.40
Shortest transaction:     0.04
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  main.rs
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C2NckSy---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/LS6esNN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C2NckSy---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/LS6esNN.png" alt="Main Mutex htop" width="700" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one passes the connection pool to all the threads, fully utilizing the CPU. This ended up taking 2.19X less time to run and had the same speedup on “Longest transaction”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;** SIEGE 4.0.4
** Preparing 100 concurrent users for battle.
The server is now under siege...
Transactions:              1000 hits
Availability:              100.00 %
Elapsed time:              17.10 secs
Data transferred:          0.00 MB
Response time:             1.57 secs
Transaction rate:          58.48 trans/sec
Throughput:                0.00 MB/sec
Concurrency:               91.82
Successful transactions:   1000
Failed transactions:       0
Longest transaction:       3.58
Shortest transaction:      0.07
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go ahead and &lt;a href="https://github.com/chmoder/rust-practice-warp"&gt;check out the repository on GitHub&lt;/a&gt;! Let me know what you think and what kind of modifications you were able to do!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>warp</category>
      <category>api</category>
      <category>redis</category>
    </item>
  </channel>
</rss>
