<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Jakub Dziworski</title>
		<description>Jakub Dziworski's JVM dev blog</description>
		<link>https://jakubdziworski.github.io/</link>
		<atom:link href="https://jakubdziworski.github.io/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>Cassandra Updates Ordering</title>
				<description>&lt;p&gt;When faced with a task of picking a database for a project we need to consider a lot of tradeoffs.
Finding &lt;strong&gt;and fully understanding&lt;/strong&gt; the limitations and implications of using each candidate databases is very hard.
It’s often the case that some database behaviors, which have huge impact on our use case, are buried deep in the documentation or even
require diving into the codebase. For me personally, one of those unexpected behaviors was the way Cassandra updates ordering works.&lt;/p&gt;

&lt;h2 id=&quot;ordering-is-tricky&quot;&gt;Ordering is tricky&lt;/h2&gt;

&lt;p&gt;One of the classic problem in distributed systems is ordering of messages. It’s problematic in cases when concurrent
updates for the same key can be proposed. In such case nodes have to somehow agree on what is the actual order.
The problem is however, way easier to solve if there are no concurrent updates.
Since Cassandra is leaderless database multiple writes can be accepted by multiple nodes concurrently.
It’s therefore crucial to understand how Cassandra handles such cases. Here are some quotes from the &lt;a href=&quot;https://cassandra.apache.org/doc/latest/cassandra/architecture/dynamo.html&quot;&gt;documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;As every replica can independently accept mutations to every key that it owns, every key must be &lt;strong&gt;versioned&lt;/strong&gt;.
Unlike in the original Dynamo paper where deterministic versions and vector clocks were used to reconcile &lt;strong&gt;concurrent&lt;/strong&gt; updates to a key, Cassandra uses a simpler &lt;strong&gt;last write wins&lt;/strong&gt; model where every mutation is timestamped (including deletes) and then the latest version of data is the “winning” value&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Later in the same page it’s mentioned that:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Specifically all mutations that enter the system do so with a timestamp provided either from a client clock or, absent a client provided timestamp, from the coordinator node’s clock. Updates resolve according to the &lt;strong&gt;conflict resolution rule of last write wins&lt;/strong&gt;. Cassandra’s correctness does depend on these clocks, so make sure a proper time synchronization process is running such as NTP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and also:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Rows are guaranteed to be unique by primary key, and &lt;strong&gt;each column in a row resolve concurrent mutations according to last-write-wins conflict resolution&lt;/strong&gt;. This means that updates to different primary keys within a partition can actually resolve without conflict&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I may be an exception, but after reading the documentation I personally came to conclusion that Cassandra only needs to resolve conflicts
if there are concurrent updates (and uses timestamp for that). I came to this conclusion after reading docs, since there are:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Mentions of “&lt;strong&gt;concurrent&lt;/strong&gt;” updates in sections describing reconciliation/conflict resolution.&lt;/li&gt;
  &lt;li&gt;Mentions of “&lt;strong&gt;versioned key&lt;/strong&gt;” statements. To me this indicates there is some kind of version ordering implemented (something equivalent to MVCC or vector clock in Dynamo).&lt;/li&gt;
  &lt;li&gt;Comparisons to Dynamo’s reconciliation process, that implements ordering based on vector clock. In such implementation only concurrent updates impose problem for ordering.&lt;/li&gt;
  &lt;li&gt;Mentions of “&lt;strong&gt;Last Write Wins&lt;/strong&gt;” which hints that “whatever is written last, wins”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was not sure if my understanding of documentation is correct, so I decided to test that.&lt;/p&gt;

&lt;h2 id=&quot;no-logical-ordering-only-timestamps-matter&quot;&gt;No logical ordering, only timestamps matter&lt;/h2&gt;

&lt;p&gt;Turns out my assumptions were wrong and conflict resolutions occur even when there are no concurrent updates. If a single client sends updates to
Cassandra cluster (sequentially with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CONSISTENCY=ALL&lt;/code&gt;) there is no guarantee that the final value is going to be the last
one that the client has sent. Basically, &lt;strong&gt;when performing standard insert/update, all that matters is the timestamp attached to the value&lt;/strong&gt;.
It doesn’t matter what was the actual order of applied updates. If timestamp of new value happens to be
smaller than timestamp of existing value, new value will simply be discarded. Cassandra only relies on timestamps provided by client or node itself
(with some exceptions mentioned few sections below).
How are those timestamps picked then?&lt;/p&gt;

&lt;h3 id=&quot;timestamps-generated-by-cassandra-nodes&quot;&gt;Timestamps generated by Cassandra nodes&lt;/h3&gt;
&lt;p&gt;The timestamp for a statement can be provided either by the client or the coordinator node (the node that received request from a client).
&lt;strong&gt;If there is a clock skew&lt;/strong&gt; between cassandra nodes in a cluster, even if your client is sending requests sequentially (using load balancer) the final value
might may not be the last one even though there was no concurrent updates and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CONSISTENCY&lt;/code&gt; was set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALL&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;timestamps-generated-by-clients&quot;&gt;Timestamps generated by clients&lt;/h3&gt;
&lt;p&gt;Similarly, imagine you have a stateless app that sends updates to cassandra. This app has multiple instances which are
reachable via load balancer using round-robin. Timestamps for Cassandra updates are set by clients (your app instances),
but the clocks are out of sync. Since clocks on those clients are all over the place, the timestamps assigned to updates received by cassandra would also be all over the place.
Even if you perform requests to the load balancer sequentially the final value might therefore may not be the last one.&lt;/p&gt;

&lt;h2 id=&quot;testing-ordering-wth-out-of-sync-clocks&quot;&gt;Testing ordering wth out of sync clocks&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/JakubDziworski/cassandra-ordering-clock-skew-test&quot;&gt;Test source code available on github.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to test those scenarios I created a 3 node cassandra cluster using docker compose. Since docker containers
share clock with host, all the cassandra nodes are perfectly in sync. In order to simulate clock skews I used libfaketime to set clocks as follows:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Cassandra 1: &lt;strong&gt;3 seconds behind host&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Cassandra 2: &lt;strong&gt;6 seconds behind host&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Cassandra 3: &lt;strong&gt;9 seconds behind host&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also had to make a small tweak to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cqlsh.py&lt;/code&gt; to make sure server timestamps are used: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self.session.use_client_timestamp=False&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After starting the cluster and creating test tables I run following script:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-SHELL&quot;&gt;docker exec -it cass1 cqlsh -e &quot;CONSISTENCY ALL; INSERT INTO ordering_test.ordering_test(key, value) VALUES(&apos;key&apos;, &apos;value_1&apos;)&quot;
echo &quot;Inserted &apos;value_1&apos;&quot;

docker exec -it cass2 cqlsh -e &quot;CONSISTENCY ALL; INSERT INTO ordering_test.ordering_test(key, value) VALUES(&apos;key&apos;, &apos;value_2&apos;)&quot;
echo &quot;Inserted &apos;value_2&apos;&quot;

echo &quot;Selecting current value&quot;
docker exec -it cass3 cqlsh -e &quot;CONSISTENCY ALL; SELECT * FROM ordering_test.ordering_test&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first insert statement is sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cass1&lt;/code&gt; while second statement is sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cass2&lt;/code&gt;. The select statement is sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cass3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since consistency is set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALL&lt;/code&gt; and queries are executed sequentially (there is no concurrency) it’s logical to expect that the final value
would be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_2&lt;/code&gt;, right? However, &lt;strong&gt;since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cass2&lt;/code&gt; clock is 3 seconds behind &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cass1&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_1&lt;/code&gt; has greater timestamp than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_2&lt;/code&gt; and
final result is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_1&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-SHELL&quot;&gt;Consistency level set to ALL.
Inserted &apos;value_1&apos;

Consistency level set to ALL.
Inserted &apos;value_2&apos;

Selecting current value
Consistency level set to ALL.

 key | value
-----+---------
 key | value_1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I also wanted to make sure if timestamp of select doesn’t affect the result. AFAIK Cassandra doesn’t support MVCC or any similar
feature, but it’s worth testing. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cass3&lt;/code&gt; (which is used for performing select at the end) has the biggest clock drift (9 seconds behind host).
If there was MVCC-like feature present, the select should therefore return an empty value.
After all, when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cass3&lt;/code&gt; performs select, there is no value with timestamp &amp;lt;= &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cass3&lt;/code&gt;’s timestamp.
We can debug this by adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SELECT dateof(now()) FROM system.local&lt;/code&gt; to each command like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-SHELL&quot;&gt;docker exec -it cass1 cqlsh -e &quot;CONSISTENCY ALL; INSERT INTO ordering_test.ordering_test(key, value) VALUES(&apos;key&apos;, &apos;value_1&apos;); SELECT dateof(now()) FROM system.local&quot;
echo &quot;Inserted &apos;value_1&apos;&quot;

docker exec -it cass2 cqlsh -e &quot;CONSISTENCY ALL; INSERT INTO ordering_test.ordering_test(key, value) VALUES(&apos;key&apos;, &apos;value_2&apos;); SELECT dateof(now()) FROM system.local&quot;
echo &quot;Inserted &apos;value_2&apos;&quot;

docker exec -it cass3 cqlsh -e &quot;CONSISTENCY ALL; SELECT dateof(now()) FROM system.local, * FROM ordering_test.ordering_test; SELECT dateof(now()) FROM system.local&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Results:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-SHELL&quot;&gt;Consistency level set to ALL.

 system.dateof(system.now())
---------------------------------
 2022-11-14 17:26:51.706000+0000

Inserted &apos;value_1&apos;



Consistency level set to ALL.

 system.dateof(system.now())
---------------------------------
 2022-11-14 17:26:49.927000+0000

Inserted &apos;value_2&apos;


Selecting current value
Consistency level set to ALL.

 key | value
-----+---------
 key | value_1
 
 system.dateof(system.now())
---------------------------------
 2022-11-14 17:26:47.828000+0000
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, timestamp at each subsequent statement is smaller than the previous one. This indicates that select timestamp doesn’t influence the results.&lt;/p&gt;

&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;

&lt;p&gt;According to my research the reconciliation is implemented by &lt;a href=&quot;shttps://github.com/apache/cassandra/blob/c378874a9fa123891d1d75177d99dba5c4d18f9b/src/java/org/apache/cassandra/db/rows/Cells.java#L68&quot;&gt;Cell.reconcile(c1, c2)&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reconcile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isCounterCell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isCounterCell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resolveCounter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resolveRegular&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see above counter cells are handled different (more about it in the next section). Apart from that, the reconciliation process for regular cells is very simple and purely based on timestamps.
If timestamps are different, value with higher timestamp is picked:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;leftTimestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rightTimestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;leftTimestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rightTimestamp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;leftTimestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rightTimestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In rare scenario when timestamps are the same, tombstones are prioritezed. If there are no tombstones then greater value is picked:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;compareValues&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;are-there-any-exceptions-to-timestamp-based-ordering&quot;&gt;Are there any exceptions to timestamp based ordering?&lt;/h2&gt;

&lt;p&gt;To make things more fun there seems to be some exceptions. There are probably more - those are just the ones I encountered.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COUNTER&lt;/code&gt; columns updates actually behave as we would expect. Instead of using timestamps, cells of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COUNTER&lt;/code&gt;
&lt;a href=&quot;https://github.com/apache/cassandra/blob/c378874a9fa123891d1d75177d99dba5c4d18f9b/src/java/org/apache/cassandra/db/rows/Cells.java#L121&quot;&gt;merges conflicting values&lt;/a&gt;. It makes sense, since counters can only be updated
by some delta (They can’t be set to specific value). Since counter can only be updated by delta, the order of how those deltas are applied really doesn’t matter, does it?&lt;/p&gt;

&lt;p&gt;Cassandra supports lightweight transactions that are using paxos in order to achieve a consensus for a new value proposed by one of the nodes.
In our example, it can be triggered by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IF EXISTS&lt;/code&gt; like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-SHELL&quot;&gt;UPDATE ordering_test.ordering_test SET value = &apos;value_1&apos; where key = &apos;key&apos; IF EXISTS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By using lightweight transactions the actual ordering of updates is respected and the final value is indeed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value_2&lt;/code&gt; as we would expect.
However, since paxos is used, a lot of communication between nodes is required to achieve consensus which probably has serous performance implications.&lt;/p&gt;

&lt;h2 id=&quot;what-can-we-do-about-it&quot;&gt;What can we do about it?&lt;/h2&gt;

&lt;p&gt;We should try to keep our servers clocks in sync. Both clients and Cassandra servers. Properly configured NTP, however, doesn’t guarantee that there will be no problems
mentioned above as there can always be some small drifts. Here are few ideas I came up wth to eliminate or at least reduce to minimum clock related issues:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Simply do not update existing values at all. If we only insert new values without conflicting keys the problem basically does not exist. Instead of updating you can add new entries and periodically remove old ones. If using CQRS pattern you can even use separate database for serving reads and use cassandra only for writes and streaming events to the read side.&lt;/li&gt;
  &lt;li&gt;Use client timestamps and always perform updates for the same key from the same client. This can be achieved by having consistent hashing so that the same client receives requests for the same entity all the time.&lt;/li&gt;
  &lt;li&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;USING TIMESTAMP&lt;/code&gt; in your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INSERT&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UPDATE&lt;/code&gt; explicitly. If your data already has some notion of timestamps/ordering key you can use it to set timestamp on a row explicitly.&lt;/li&gt;
  &lt;li&gt;Use lightweight transactions, but be aware of decreased performance.&lt;/li&gt;
  &lt;li&gt;If possible, model your column using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COUNTER&lt;/code&gt; type (however it has another set of limitations and quirks).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I missed something or some of my conclusions are wrong please let me know in the comments.&lt;/p&gt;
</description>
				<pubDate>Tue, 22 Nov 2022 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/java/cassandra/database/2022/11/22/cassandra-updates-ordering.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/java/cassandra/database/2022/11/22/cassandra-updates-ordering.html</guid>
			</item>
		
			<item>
				<title>Arduino OBD DPF monitor</title>
				<description>&lt;p&gt;If you own a diesel car chances are you know about issues caused by unsupervised DPF burnouts.
Knowing when DPF soot is going to be burned out and what is the current status of burning is crucial for keeping many vehicle components in good condition.&lt;/p&gt;

&lt;iframe width=&quot;840&quot; height=&quot;425&quot; src=&quot;https://www.youtube.com/embed/UeFjWw24aRw&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h1 id=&quot;existing-solutions-for-monitoring-dpf&quot;&gt;Existing solutions for monitoring DPF&lt;/h1&gt;

&lt;p&gt;How can you monitor it then? There are few ways:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Having car that can display DPF information by default. Unfortunately most vehicles don’t provide any information about DPF on dashboard (does anybody know why?).&lt;/li&gt;
  &lt;li&gt;LED burnout indicator. When burning soot many cars turn on additional electronic devices to create higher load on engine. One of such devices is mirror heater.
You can simply install LED by attaching it to the same circuit mirror heater use. When soot is being burned, mirror heats and LED turns on. The 
drawback of this solution is we don’t get to know DPF fill percentage, burning status or kms since last regeneration. If we don’t
 know the DPF fill percentage we can’t predict when the process is going to trigger.
 It can therefore happen in the middle of busy traffic downtown which would suck.&lt;/li&gt;
  &lt;li&gt;Use OBD scanner and smarphone app like &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.insigniadpfgmail.opldpfmonitorfree&quot;&gt;OPL DPF MONITOR&lt;/a&gt;.
 This solution provides all the information we need. The drawback is we have to turn on app each time, connect to bluetooth and mount the phone in visible place.
 Whole process is too tedious for me to do every time. On top of that screen is active all the time which drains a lot of battery. We also can’t use phone’s bluetooth for other purposes (playing music etc.).&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;arduino--obd--3&quot;&gt;Arduino + OBD = &amp;lt;3&lt;/h1&gt;

&lt;p&gt;We can however replace smartphone with arduino to display results on LCD.
It will turn on, connect and turn off automatically when entering and leaving the car.&lt;/p&gt;

&lt;p&gt;The solution I developed is for Opel Insignia but should work for any car. 
I tested few different combination of bluetooth modules and OBD readers. Some of them were either unable to
read Insignia PIDs (these are non standard OBD codes), or they were unable to communicate with each other over bluetooth. Pay extra
attention to what components you buy.&lt;/p&gt;

&lt;p&gt;We’re gonna need:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Arduino Nano&lt;/li&gt;
  &lt;li&gt;OBD reader - iCar2 Vgate Bluetooth 3.0 (many cheap ELM327s do not work)&lt;/li&gt;
  &lt;li&gt;Bluetooth module - HC-05 v3 (v2 won’t work)&lt;/li&gt;
  &lt;li&gt;2x16 LCD with i2c converter&lt;/li&gt;
  &lt;li&gt;3d printer (optional)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Arduino uses HC-05 bluetooth module to communicate with OBD reader.
Results are displayed on LCD which is also connected to arduino.&lt;/p&gt;

&lt;h1 id=&quot;wiring&quot;&gt;Wiring&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/arduino_dpf_monitor_insignia/dpf_monitor_schematic.png&quot; alt=&quot;WiringSchematic&quot; /&gt;
&lt;img src=&quot;/assets/media/arduino_dpf_monitor_insignia/insignia_monitor_wiring_photo.jpg&quot; alt=&quot;WiringSchematicPhoto&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;hc-05-bluetooth-module&quot;&gt;HC-05 bluetooth module&lt;/h2&gt;

&lt;p&gt;Communication between arduino and HC-05 module is done over UART. We don’t want to use hardware serial (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RX,TX&lt;/code&gt; pins) - 
afaik if we did we wouldn’t be able to debug using PC. Since we don’t need super high speed software serial is more than enough so we can use any digital pin.
Pin 10 and 7 were therefore chosen. Since HC-05 expects 3.3v to be sent to it’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RX&lt;/code&gt; pin we add voltage divider composed of 2k and 1k resistors
to reduce arduino’s digital output from 5v to 3.3v.&lt;/p&gt;

&lt;p&gt;We also need to be able to reset and reconfigure HC-05 using arduino. This is neccessary in order to pair with new OBD reader device. 
HC-05 will then be unable to connect with it and will need reconfiguration.&lt;/p&gt;

&lt;p&gt;In order to boot HC-05 into configuration mode it’s 34pin has to be pulled HIGH (5v) and the module has to be reset. We use arduino
digital pin 5 and 4 for that purposes.&lt;/p&gt;

&lt;h2 id=&quot;bluetooth-configration-button&quot;&gt;Bluetooth configration button&lt;/h2&gt;

&lt;p&gt;The purpose of button is to allow user to trigger HC-05 configuration. It’s required after new OBD reader is used or existing
OBD reader was used with different device.&lt;/p&gt;

&lt;h2 id=&quot;onoff-switch&quot;&gt;On/off switch&lt;/h2&gt;
&lt;p&gt;Even though the device will automatically turn itself on and off when user enters/leaves the car (it’s using same circuit as 12v lighter socket)
 it’s a nice feature to have.&lt;/p&gt;

&lt;h2 id=&quot;lcd&quot;&gt;LCD&lt;/h2&gt;
&lt;p&gt;2x16 LCD alone requires a lot of wires to work with arduino. It’s easier to solder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2c&lt;/code&gt; converter to it and just connect 2
wires to arduino.&lt;/p&gt;

&lt;h2 id=&quot;lighter-socket-power-supply&quot;&gt;Lighter socket power supply&lt;/h2&gt;
&lt;p&gt;In my opinion 12v lighter socket is the best source of power. It will turn on when ignition is turned on. It will turn off
when user leaves car (opens door after turning off engine). In case of Insignia it is also in a very convenient place. Next to the
lighter socket there is handy hole that we can use for placing and hiding guts of our device. It’s very easy to solder directly to lighter socket on the back
where it is not visible. You will however need to disassemble panel that holds it in place and unplug the lighter socket.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/arduino_dpf_monitor_insignia/insignia_monitor_lighter_socket_cables.jpg&quot; alt=&quot;LighterSockerCables&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;plastic-case&quot;&gt;Plastic case&lt;/h2&gt;
&lt;p&gt;You can download 3d model &lt;a href=&quot;https://www.tinkercad.com/things/2WSSeYlX7tc&quot;&gt;here&lt;/a&gt;. It will lock in nicely into the hole that is next to the lighter socket in Opel Insignia. If you dont have a 3d printer
you can buy/find existing case and cut hole for lcd.&lt;/p&gt;

&lt;h1 id=&quot;coding&quot;&gt;Coding&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/JakubDziworski/insignia-dpf-monitor&quot;&gt;Click here to get full code from github.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to pull 3 types of data from a car:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;DPF regeneration status. 0 if not burning. 1-255 if burning (percentage completed).&lt;/li&gt;
  &lt;li&gt;DPF fill percentage (0-100).&lt;/li&gt;
  &lt;li&gt;Distance since last burnout (in kms).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In case of Opel Insignia these are following PIDs - (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;223274&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;223275&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;223277&lt;/code&gt;).
Finding PID codes for your car might be challenging. Personally I couldn’t find anything online. 
I ended up sniffing what commands are sent by &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.insigniadpfgmail.opldpfmonitorfree&quot;&gt;OPL DPF MONITOR&lt;/a&gt; android app.
I used a &lt;a href=&quot;https://stackoverflow.com/questions/23877761/sniffing-logging-your-own-android-bluetooth-traffic&quot;&gt;method describere here&lt;/a&gt; to sniff bluetooth traffic.&lt;/p&gt;

&lt;p&gt;PID is just a command that is understood by at least one of the car’s module.
Because above PIDs are not standardized we also need to provide header. Header is 
a destination for a PID command to be issued. This tells OBD reader to send it to specific car’s module.
In case of Insignia it is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7E0&lt;/code&gt; which is just an engine computer.&lt;/p&gt;

&lt;p&gt;To retrieve data we therefore need to first set header to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7E0&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vgate.sendCommand(&quot;AT SH 7E0&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Afterwards we can query PIDs:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int32_t getRegenerationStatus() {
  return queryVgate(0x22, 0x3274);
}

int32_t getKmsSinceDpf() {
  return queryVgate(0x22, 0x3277);
}

int32_t getDpfDirtLevel() {
  return queryVgate(0x22, 0x3275);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Luckily &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ELMduino&lt;/code&gt; library handles all the details when it comes to communication with OBD reader. Just make
sure you use newest version. It seems to be actively developed.
I personally found one edge case and submitted PR - maintainer approved and merged it the same day.&lt;/p&gt;

&lt;p&gt;To display values on the lcd simply use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LiquidCrystal_I2C&lt;/code&gt; library like so:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lcd.clear();
lcd.setCursor(0,0);
String message = &quot;LAST: &quot;;
message = message + kmsSinceDpf + &quot;KM&quot;;
lcd.print(message);
lcd.setCursor(0,1);
message = &quot;FILL: &quot;;
message = message + dirtLevel + &quot;%&quot;;
lcd.print(message);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h1 id=&quot;hc-05-auto-configuration&quot;&gt;HC-05 auto-configuration&lt;/h1&gt;

&lt;p&gt;In order to pair HC-05 module with OBD reader it needs to be launched in configuration mode. This is done by either
pressing and holding button on the HC-05 module or setting pin 34 to high when powering. 
This project makes the process automatic when “TRIGGER PAIRING WITH OBD READER BUTTON” is held. It will
 set pin 34 to high and reset HC-05 module. Afterwards arduino will send all the necessary pairing commands, set pin 34 to low
 and reset HC-05 again. Afterwards it will launch into normal mode and start connecting to paired OBD reader every time it is powered on.
Just make sure to replace your OBD reader bluetooth address in the code:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sendCommand(&quot;AT+BIND=86DC,3D,ABF7F1&quot;);
sendCommand(&quot;AT+PAIR=86DC,3D,ABF7F1,20&quot;,10000L);
sendCommand(&quot;AT+LINK=86DC,3D,ABF7F1&quot;,10000L);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Don’t worry if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AT+INIT&lt;/code&gt; command returns ERROR. It’s “normal” for v3 module according to online resources :).&lt;/p&gt;
</description>
				<pubDate>Mon, 13 Jul 2020 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/obd/bluetooth/arduino/car/2020/07/13/arduino-obd-dpf-monitor-insignia.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/obd/bluetooth/arduino/car/2020/07/13/arduino-obd-dpf-monitor-insignia.html</guid>
			</item>
		
			<item>
				<title>Applied Akka Patterns - Book Review</title>
				<description>&lt;p&gt;I recently watched &lt;a href=&quot;https://youtu.be/MnNeDXg3Qao&quot;&gt;Wade Waldron’s talk “Domain Driven Design and Onion Architecture in Scala”&lt;/a&gt; 
which I found really great. What stood out was Wade’s gift for explaining confusing topics
 in a way that anyone could understand.&lt;/p&gt;

&lt;p&gt;Few days later I googled dude’s name and it turned out him and Michael Nash are 
about to release a book called “Applied Akka Patterns”. I skimmed through the table of contents 
and was initially going to read only one chapter, but damn, this book turned out to be excellent and I had to read it cover to cover.&lt;/p&gt;

&lt;h2 id=&quot;so-many-questions-answered&quot;&gt;So many questions answered&lt;/h2&gt;

&lt;p&gt;When I first started learning Akka I had so many questions and there was no one to answer.&lt;/p&gt;

&lt;p&gt;Should entire system be based on actor model or can I just use it parts of it?
How to deal with blocking operations? When to use futures and when to use actors?
How does DDD fit into akka? How to monitor and find bottlenecks in akka based system? 
Which operations deserve separate dispatcher? “Tell don’t ask” - when should I use ask then? 
Which supervision strategies are useful in which scenarios?
I found answer to those questions on my long and painful path reading other people’s code and 
finding fragmented information here and there.&lt;/p&gt;

&lt;p&gt;The book answers all those questions and many many more. It amazes me how much useful content is packed into such a small volume (200 pages).
Some books leave you with more questions than you had had before you grabbed it - not this one. There were numerous times when I was reading a paragraph and thought to myself “Oh, that’s fine but what about…?” and then
the answer was found right there on the next page. It almost feels like the authors took some beginner akka programmer, asked
to read the chapter and write all the questions down.
I also like that the book is very pragmatic - the theory is compressed to absolute minimum and almost all statements are backed up by practical examples - even chapter regarding DDD.&lt;/p&gt;

&lt;p&gt;The book is full of useful information. Here are just some off the top of my head:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The world is asynchronous so why model it in a synchronous way?&lt;/li&gt;
  &lt;li&gt;When, and at what scale should you use actors&lt;/li&gt;
  &lt;li&gt;How to implement D(distributed)DDD with akka.&lt;/li&gt;
  &lt;li&gt;Different ways to handle state changes within an actor&lt;/li&gt;
  &lt;li&gt;Handling long running operations within the actor&lt;/li&gt;
  &lt;li&gt;Alternatives to using ask pattern, and when it is ok to use ask&lt;/li&gt;
  &lt;li&gt;Where to keep message classes&lt;/li&gt;
  &lt;li&gt;How to structure messages flow to achieve best throughput and latency&lt;/li&gt;
  &lt;li&gt;How to prevent mailbox overflow&lt;/li&gt;
  &lt;li&gt;Consistency vs. Scalability and how akka sharding can help with balancing them&lt;/li&gt;
  &lt;li&gt;Isolating failures and self healing&lt;/li&gt;
  &lt;li&gt;Preparing for failures even at the jvm level&lt;/li&gt;
  &lt;li&gt;Maximize availability&lt;/li&gt;
  &lt;li&gt;Find bottlenecks within jvm and akka itself&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;for-who&quot;&gt;For who?&lt;/h2&gt;

&lt;p&gt;I feel like when getting started with akka you are given this massive set of tools and you neither have an idea
which ones are best suited for certain situations, nor what are best practices.
There are gazillions of resources describing what is akka and how to get started with it. 
What is lacking though are set of best practices and common patterns.
Akka toolkit is really dangerous when put in the wrong hands. We, beginner/intermediate akka users, need those patterns and best practices 
compiled into one resource to protect against those mistakes. I think the book aims for this niche and nails it flawlessly.&lt;/p&gt;

&lt;h2 id=&quot;final-rant&quot;&gt;Final rant&lt;/h2&gt;

&lt;p&gt;One thing I missed was some kind of a bullet point list below each chapter with the most important statements. The book has so much material
that I had to write my own notes, otherwise I would not be able to retain all the information.&lt;/p&gt;

</description>
				<pubDate>Tue, 27 Dec 2016 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/scala/akka/book/2016/12/27/applied-akka-patterns-book-review.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/scala/akka/book/2016/12/27/applied-akka-patterns-book-review.html</guid>
			</item>
		
			<item>
				<title>Implementing Websocket Game Server with Scala and Akka Streams [Part 4/4]</title>
				<description>&lt;iframe width=&quot;840&quot; height=&quot;425&quot; src=&quot;https://www.youtube.com/embed/gqHgnbDBTIw&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;This is the last part where I code a client.&lt;/p&gt;

&lt;p&gt;Thanks to everyone who watched the series!
I know at times it was a bit hard to follow.
I’ve made a mistake of coding and trying talk at the same time. 
It turns out it is a really hard and you cannot fully focus on both.
Next time I’m going to do one thing at the time and then merge it in post-production.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href=&quot;https://github.com/JakubDziworski/Akka-Streams-Websocket-Game-Server&quot;&gt;https://github.com/JakubDziworski/Akka-Streams-Websocket-Game-Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other parts: &lt;a href=&quot;https://jakubdziworski.github.io/categories.html#Game-Server-with-Scala-and-Akka-Streams-ref&quot;&gt;Implementing Websocket Game Server with Scala and Akka Streams&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 11 Oct 2016 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/scala/game%20server%20with%20scala%20and%20akka%20streams/2016/10/11/implemeting-game-server-akka-scala-streams-http-websocket-part4.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/scala/game%20server%20with%20scala%20and%20akka%20streams/2016/10/11/implemeting-game-server-akka-scala-streams-http-websocket-part4.html</guid>
			</item>
		
			<item>
				<title>Implementing Websocket Game Server with Scala and Akka Streams [Part 3/4]</title>
				<description>&lt;iframe width=&quot;840&quot; height=&quot;425&quot; src=&quot;https://www.youtube.com/embed/PTWLO5Gclh0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Last part of server side implementation.
The remaining piece of the puzzle is client side which is next part’s subject.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href=&quot;https://github.com/JakubDziworski/Akka-Streams-Websocket-Game-Server&quot;&gt;https://github.com/JakubDziworski/Akka-Streams-Websocket-Game-Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other parts: &lt;a href=&quot;https://jakubdziworski.github.io/categories.html#Game-Server-with-Scala-and-Akka-Streams-ref&quot;&gt;Implementing Websocket Game Server with Scala and Akka Streams&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 03 Oct 2016 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/scala/game%20server%20with%20scala%20and%20akka%20streams/2016/10/03/implemeting-game-server-akka-scala-streams-http-websocket-part3.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/scala/game%20server%20with%20scala%20and%20akka%20streams/2016/10/03/implemeting-game-server-akka-scala-streams-http-websocket-part3.html</guid>
			</item>
		
			<item>
				<title>Implementing Websocket Game Server with Scala and Akka Streams [Part 2/4]</title>
				<description>&lt;iframe width=&quot;840&quot; height=&quot;425&quot; src=&quot;https://www.youtube.com/embed/Au5zQmmgZUg&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Second part of server side implementation.&lt;/p&gt;

&lt;p&gt;Code: &lt;a href=&quot;https://github.com/JakubDziworski/Akka-Streams-Websocket-Game-Server&quot;&gt;https://github.com/JakubDziworski/Akka-Streams-Websocket-Game-Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other parts: &lt;a href=&quot;https://jakubdziworski.github.io/categories.html#Game-Server-with-Scala-and-Akka-Streams-ref&quot;&gt;Implementing Websocket Game Server with Scala and Akka Streams&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 29 Sep 2016 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/scala/game%20server%20with%20scala%20and%20akka%20streams/2016/09/29/implemeting-game-server-akka-scala-streams-http-websocket-part2.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/scala/game%20server%20with%20scala%20and%20akka%20streams/2016/09/29/implemeting-game-server-akka-scala-streams-http-websocket-part2.html</guid>
			</item>
		
			<item>
				<title>Implementing Websocket Game Server with Scala and Akka Streams [Part 1/4]</title>
				<description>&lt;iframe width=&quot;840&quot; height=&quot;425&quot; src=&quot;https://www.youtube.com/embed/lex7xQPgzY8&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;First part of server side implementation&lt;/p&gt;

&lt;p&gt;Code: &lt;a href=&quot;https://github.com/JakubDziworski/Akka-Streams-Websocket-Game-Server&quot;&gt;https://github.com/JakubDziworski/Akka-Streams-Websocket-Game-Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other parts: &lt;a href=&quot;https://jakubdziworski.github.io/categories.html#Game-Server-with-Scala-and-Akka-Streams-ref&quot;&gt;Implementing Websocket Game Server with Scala and Akka Streams&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 22 Sep 2016 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/scala/game%20server%20with%20scala%20and%20akka%20streams/2016/09/22/implemeting-game-server-akka-scala-streams-http-websocket-part1.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/scala/game%20server%20with%20scala%20and%20akka%20streams/2016/09/22/implemeting-game-server-akka-scala-streams-http-websocket-part1.html</guid>
			</item>
		
			<item>
				<title>Github Code Search - Programmers' Goldmine</title>
				<description>&lt;p&gt;Learning new language or framework can sometimes be a struggle. Traditional approach is to read documentation which explains the concepts, and provides simple examples.
Sometimes that might be enough, but what those documentations are often lacking are some advanced examples and usages in real projects.&lt;/p&gt;

&lt;p&gt;Coming across a problem which is not described in documentation, most people look for solution on stackoverflow (or dig through sources).
However the framework you are using might not be in the game for long enough to fill stackoverflow with every question you come up with.&lt;/p&gt;

&lt;p&gt;Have you ever been stuck with a problem and thought to yourself:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;“I know someone must have solved this before! Why there is no stackoverflow answer to this problem?”&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You are right - someone has probably already solved it. And it’s very likely the solution has been pushed to github.
It’s just a matter of finding it. Programmers are more likely to solve the issues themselves rather than ask random people on the internet about it.&lt;/p&gt;

&lt;h1 id=&quot;github-search-code&quot;&gt;Github search code&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/search&quot;&gt;Github search&lt;/a&gt; provides a way to query repos in a various ways. One of them is &lt;a href=&quot;https://developer.github.com/v3/search/#search-code&quot;&gt;searching code&lt;/a&gt;.
This is extremly powerful feature. Every line ever written by anybody can be found with simple queries.
The “good” thing about github is that the private repos are not free, so there are many projects implicitly shared to public by people who just want to backup their code. This is a goldmine of information!&lt;/p&gt;

&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;/h2&gt;

&lt;p&gt;Below are some of the examples which I find github search code is handy for.&lt;/p&gt;

&lt;h3 id=&quot;learning-new-api&quot;&gt;Learning new api&lt;/h3&gt;

&lt;p&gt;Have you ever been stuck with 3rd party api, and unable to find similar code snippets for your case?&lt;/p&gt;

&lt;p&gt;I was recently in need to use &lt;strong&gt;akka streams&lt;/strong&gt; to read a huge file and pass the results to another file instantly.
The &lt;a href=&quot;http://doc.akka.io/docs/akka/2.4/scala/stream/stream-io.html#Streaming_File_IO&quot;&gt;documentation&lt;/a&gt; regarding
 this topic is good but short and could provide more examples.&lt;/p&gt;

&lt;p&gt;Github advanced search to the rescue. After few clicks I found an awesome piece of code
that streams the csv file modifies it and dumps to another file!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/github_search/filepaths_example.gif&quot; alt=&quot;filepaths_example&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;finding-projects-using-technologies-you-are-interested-in&quot;&gt;Finding projects using technologies you are interested in&lt;/h3&gt;

&lt;p&gt;Let’s say you want to learn &lt;strong&gt;Spring MVC&lt;/strong&gt;, &lt;strong&gt;Hibernate&lt;/strong&gt; and testing with &lt;strong&gt;Spock&lt;/strong&gt;. You could go to the docs
of each libraries, and learn them one by one… or just find a project which integrates all of them.&lt;/p&gt;

&lt;p&gt;Most platforms have some kind of dependency management tools. In case of &lt;strong&gt;Java&lt;/strong&gt; that is 
usually &lt;strong&gt;Maven&lt;/strong&gt; which stores all dependencies information in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pom.xml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;You can therefore query keywords and filename to find the projects you are interested in:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;spring hibernate spock filename:pom.xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This method is also
great if you are looking for projects to contribute to.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/github_search/find_technology.gif&quot; alt=&quot;find_technology&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;integrating-with-external-services&quot;&gt;Integrating with external services&lt;/h3&gt;

&lt;p&gt;Looking for a quick way to integrate with github api using your favourite language? No problem - just look for
the repos with the api url and filter by language:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;api.github.com language:scala
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/github_search/find_integrations.gif&quot; alt=&quot;find_integrations&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;configuration&quot;&gt;Configuration&lt;/h3&gt;

&lt;p&gt;It also wouldn’t hurt to take a look at configuration files of real big projects.
This might be extremly helpful, particularly in case of immature frameworks.&lt;/p&gt;

&lt;p&gt;Let’s take a look how to configure akka cluster. Such configuration should
contain &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClusterActorRefProvider&lt;/code&gt; keyword and reside in file with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.conf&lt;/code&gt; extension (usually &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;application.conf&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ClusterActorRefProvider extension:conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/media/github_search/find_configuration.gif&quot; alt=&quot;find_configuration&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Github search is underrated yet extremly powerful tool for learning new apis,solving issues and finding repos you might be interested in.
This is a great way to quickly get started with new framework - finding code snippets that are similar to what you want to achieve has never been easier.
It also makes you feel less alone with the issues you encounter - it’s very likely some has already solved them. Likewise, discovering interesting projects with this
search engine is just a matter of minutes.&lt;/p&gt;
</description>
				<pubDate>Fri, 26 Aug 2016 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/tools/2016/08/26/github-code-advances-search-programmers-goldmine.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/tools/2016/08/26/github-code-advances-search-programmers-goldmine.html</guid>
			</item>
		
			<item>
				<title>JShell - Java 9 interpreter (REPL) - Getting Started and Examples</title>
				<description>&lt;p&gt;Many compiled languages include tools (sometimes called REPL) for statements interpretation.
Using these tools you can test code snippets rapidly without creating project.&lt;/p&gt;

&lt;p&gt;Take Scala as an example. Compilation can sometimes take a long time, but using repl each statement is executed instantly! That’s
great when you are getting started with the language. Each expression gives you returned value and it’s type - that’s very valuable
information.&lt;/p&gt;

&lt;p&gt;In java, instead, we have to create a test or main method which prints results and needs to be recompiled every time you make a change.&lt;/p&gt;

&lt;h1 id=&quot;when&quot;&gt;When?&lt;/h1&gt;

&lt;p&gt;JShell will be introduced in &lt;a href=&quot;http://www.java9countdown.xyz/&quot;&gt;Java 9 realease&lt;/a&gt;. You can however get early access build 
on &lt;a href=&quot;https://jdk9.java.net/&quot;&gt;https://jdk9.java.net/&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;running&quot;&gt;Running&lt;/h1&gt;

&lt;p&gt;Once you downloaded jdk9 there is a jshell executable in a bin directory. I suggest running it in verbose (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-v&lt;/code&gt;) mode for the first time:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kuba@kuba-laptop:~/repos&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;jdk-9/bin/jshell &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;
|  Welcome to JShell &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; Version 9-ea
|  For an introduction &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;: /help intro


jshell&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can go back to non verbose mode using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/set feedback normal&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;default-imports&quot;&gt;Default imports&lt;/h2&gt;

&lt;p&gt;By default you get a set of common imports:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; /imports
|    import java.util.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
|    import java.io.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
|    import java.math.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
|    import java.net.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
|    import java.util.concurrent.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
|    import java.util.prefs.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
|    import java.util.regex.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can add your own any time.&lt;/p&gt;

&lt;h2 id=&quot;expressions&quot;&gt;Expressions&lt;/h2&gt;

&lt;p&gt;You can type any valid java expression, and it will tell you the returned &lt;strong&gt;value&lt;/strong&gt;, it’s &lt;strong&gt;type&lt;/strong&gt; and &lt;strong&gt;assign&lt;/strong&gt; it to a &lt;strong&gt;variable&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; 3+3
&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 6
|  created scratch variable &lt;span class=&quot;nv&quot;&gt;$9&lt;/span&gt; : int

jshell&amp;gt; &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 6
|  value of &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; : int

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

&lt;h2 id=&quot;variables&quot;&gt;Variables&lt;/h2&gt;

&lt;p&gt;It is possible to declare variables and name them. Once you do that they become visible in the scope.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; int &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5
x &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 5
|  created variable x : int

jshell&amp;gt; x
x &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 5
|  value of x : int
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;methods&quot;&gt;Methods&lt;/h2&gt;

&lt;p&gt;You can also define methods and even replace them:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; void helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; System.out.println&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hello JShell&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
|  created method helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;

jshell&amp;gt; helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
hello JShell

jshell&amp;gt; void helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; System.out.println&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;wow, I replaced a  method&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
|  modified method helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
|    update overwrote method helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;

jshell&amp;gt; helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
wow, I replaced a  method

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

&lt;h2 id=&quot;commands&quot;&gt;Commands&lt;/h2&gt;

&lt;p&gt;Aparat from language syntax you can execute jshell commands. Some of the most useful ones (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/help&lt;/code&gt; to list all of them) are:&lt;/p&gt;

&lt;h3 id=&quot;listing-variables&quot;&gt;listing variables&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; /vars
|    int x &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0
|    double j &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;listing-methods&quot;&gt;listing methods:&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; /methods
|    &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;String,Object...&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;void
|    helloJShell &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;void
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The printf method is defined by default.&lt;/p&gt;

&lt;h3 id=&quot;listing-sources&quot;&gt;listing sources&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; /list
  14 : helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  15 : void helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; System.out.println&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;wow, I replaced a  method&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  16 : helloJShell&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;editing-sources-in-external-editor&quot;&gt;editing sources in external editor&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; /edit helloJShell
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Opens external editor, and replaces helloJShell method.&lt;/p&gt;

&lt;h1 id=&quot;example-use-cases&quot;&gt;Example use cases&lt;/h1&gt;

&lt;p&gt;After 20 years of Java without REPL one might wonder what scenarios are suitable for JShell.
Here are some examples.&lt;/p&gt;

&lt;h2 id=&quot;veryfing-return-type&quot;&gt;Veryfing return type&lt;/h2&gt;
&lt;p&gt;Remember the time you learned that dividing two integers in Java does not result in floating number? For some time
I was convinced that both numerator and denominator have to be floating for a result to be floating too. Let’s test that:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; 1/2
&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 0
|  created scratch variable &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; : int

jshell&amp;gt; 1.0/2
&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 0.5
|  created scratch variable &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt; : double

jshell&amp;gt; 1/2.0
&lt;span class=&quot;nv&quot;&gt;$3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 0.5
|  created scratch variable &lt;span class=&quot;nv&quot;&gt;$3&lt;/span&gt; : double

jshell&amp;gt; 1.0f/2
&lt;span class=&quot;nv&quot;&gt;$4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 0.5
|  created scratch variable &lt;span class=&quot;nv&quot;&gt;$4&lt;/span&gt; : float

jshell&amp;gt; 1/2.0f
&lt;span class=&quot;nv&quot;&gt;$5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 0.5
|  created scratch variable &lt;span class=&quot;nv&quot;&gt;$5&lt;/span&gt; : float
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Turns out only one of them has to be floating.&lt;/p&gt;

&lt;h2 id=&quot;testing-java-niuanses&quot;&gt;Testing Java niuanses&lt;/h2&gt;

&lt;p&gt;Did you know that comparing autoboxed integers references which values are from range -128 to 127 (inclusive) returns true (they are cached)?
You can verify that with shell in a matter of seconds:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; Integer i1 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 127
i1 &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 127

jshell&amp;gt; Integer i2 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 127
i2 &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 127

jshell&amp;gt; i1 &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; i2
&lt;span class=&quot;nv&quot;&gt;$35&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true

&lt;/span&gt;jshell&amp;gt; Integer i2 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 128
i2 &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 128

jshell&amp;gt; Integer i1 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 128
i1 &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; 128

jshell&amp;gt; i1 &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; i2
&lt;span class=&quot;nv&quot;&gt;$38&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;formatting&quot;&gt;Formatting&lt;/h2&gt;

&lt;p&gt;Sometimes the logs need to be verbose and properly formatted. This is tedious task and usually leads to few recompile cycles which
significantly slows us down. Imagine you forgot what was the format sign responsible for integers. You can quickly verify that:&lt;/p&gt;

&lt;p&gt;Let’s try &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%i&lt;/code&gt; (integer):&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;I got %i apple&quot;&lt;/span&gt;,1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
|  java.util.UnknownFormatConversionException thrown: Conversion &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;i&apos;&lt;/span&gt;
|        at Formatter&lt;span class=&quot;nv&quot;&gt;$FormatSpecifier&lt;/span&gt;.conversion &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Formatter.java:2691&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
|        at Formatter&lt;span class=&quot;nv&quot;&gt;$FormatSpecifier&lt;/span&gt;.&amp;lt;init&amp;gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Formatter.java:2717&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
|        at Formatter.parse &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Formatter.java:2565&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
|        at Formatter.format &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Formatter.java:2507&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
|        at PrintStream.format &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;PrintStream.java:977&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
|        at PrintStream.printf &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;PrintStream.java:873&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
|        at &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#s8:1)&lt;/span&gt;
|        at &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#51:1)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Oops, maybe &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%d&lt;/code&gt; (decimal) :&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jshell&amp;gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;I got %d apple&quot;&lt;/span&gt;,1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
I got 1 apple
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;JShell is a very useful tool for prototyping and testing Java code snippets. Even though it is not yet officially released I highly recommend checking it out.
There is also a JShell Java api which allows you to evaluate JShell from java.
Once the java 9 is out I bet there will be JShell integrations in most popualar IDEs - this will make
using it even more handy.&lt;/p&gt;
</description>
				<pubDate>Sun, 31 Jul 2016 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/java/2016/07/31/jshell-getting-started-examples.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/java/2016/07/31/jshell-getting-started-examples.html</guid>
			</item>
		
			<item>
				<title>Solid in practice - Liskov Substitution Principle</title>
				<description>&lt;iframe width=&quot;640&quot; height=&quot;360&quot; src=&quot;https://www.youtube.com/embed/_yb4PpJS5S0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;3rd video of the series. This time it’s all about Liskov substitution.&lt;/p&gt;

</description>
				<pubDate>Sat, 02 Jul 2016 00:00:00 +0000</pubDate>
				<link>https://jakubdziworski.github.io/solid%20in%20practice/2016/07/02/solid-liskov-substitution-principle.html</link>
				<guid isPermaLink="true">https://jakubdziworski.github.io/solid%20in%20practice/2016/07/02/solid-liskov-substitution-principle.html</guid>
			</item>
		
	</channel>
</rss>
