dwyl / phoenix-ecto-append-only-log-example

📝 A step-by-step example/tutorial showing how to build a Phoenix (Elixir) App where all data is immutable (append only). Precursor to Blockchain, IPFS or Solid!
GNU General Public License v2.0
78 stars 7 forks source link

Update Example to Phoenix v1.4 #14

Closed SimonLab closed 5 years ago

SimonLab commented 5 years ago

The example is using Phoenix 1.3 at the moment: https://github.com/dwyl/phoenix-ecto-append-only-log-example/blob/e8eee00fab8f1555ab93c2d2757c497207d81873/mix.exs#L39

We can update the Phoenix version to 1.4 and make sure all the steps are still working.

see https://github.com/dwyl/learn-phoenix-framework/issues/118#issue-378671819

SimonLab commented 5 years ago

Phoenix 1.4 is using Ecto v3.0 and the following test is failing: image

https://github.com/dwyl/phoenix-ecto-append-only-log-example/blob/e8eee00fab8f1555ab93c2d2757c497207d81873/test/append/address_test.exs#L35-L41

This is due to the new way Ecto is dealing with the precision of the timestamps (see http://blog.plataformatec.com.br/2018/10/a-sneak-peek-at-ecto-3-0-breaking-changes/): image

This means that when the get function is called, the order_by clause might not return the correct result because the test insert almost at the same time the item and the updated version: https://github.com/dwyl/phoenix-ecto-append-only-log-example/blob/e8eee00fab8f1555ab93c2d2757c497207d81873/lib/append/append_only_log.ex#L35-L48

I can see two solutions to fix this:

nelsonic commented 5 years ago

@SimonLab thank you for summarising the Ecto 3.0 changes so others can learn from your research! 😍

While I understand the reasoning behind the breaking change in Ecto to force people to no longer rely on having high-precision time in the database (let's face it: most people don't need microseconds!) I disagree with removing them as it's "dumbing down" elixir to make it more like Ruby or JS. 😞

High precision time is one of Erlang's (and thus Elixir's) best features when it comes to low-latency and we want to have it in our projects so that we can measure latency and database insert volume at a more granular level.

My preference is to use the naive_datetime_usec type so we capture the more detailed time info.

If it turns out later that we don't need microseconds in our apps, we can always refactor and adopt the Process.sleep(1000) approach (which feels "dirty" to me).

SimonLab commented 5 years ago

to recap the process for using the naive_datetime_usec:

# Configure your database
config :append, Append.Repo,
  migration_timestamps: [type: :naive_datetime_usec],
  username: "append_only",
  password: "postgres",
  database: "append_test",
  hostname: "localhost",
  pool: Ecto.Adapters.SQL.Sandbox
SimonLab commented 5 years ago

Readme and code updated with #15