Modern mobile apps are benefiting from using gRPC with Protobuf to reduce boilerplate code for their client-server
networking implementation. While directly implemented by gRPC, the library can easily implement all necessary features
for efficient file transfers.
gRPC with Protobuf is a framework to efficiently simplify the client-server networking requirements of modern
applications. One use-case where the low-level simplicity of pure HTTP maintains an advantage over gRPC is handling file
transfers: the uploading and downloading of contiguous binary block data. But gRPC can efficiently replicate all HTTP
functionality within its Protobuf message framework making it unnecessary to host separate gRPC and HTTP servers for
applications.
Expanding on the realtime Firebase implementation in the previous article, this expands the functionality allowing the
server to fetch data on-demand from an external datasource. Additionally, functionality to periodical refresh active
data which is subscribed to by connected clients transforms this database into an efficient cache to evolving external
data which can only be obtained by polling.
Job Queues are critical parts of Enterprise workloads. Complex queues use distributed nodes, state machines, and
complex scheduling to trigger and track running jobs. But when simplicity allows the best approach is to create small
idempotent jobs. The smaller the unit of work the easier progress can be tracked, jobs can be restarted or rerun with
minimal waste, composability and reuse are increased, and logic is easier to reason about. These are the same arguments
for Functional Programming and their Effect Systems, such as ZIO. Effect systems are congruent to the enterprise job
queue, with ZIO fibers performing work and ZIO Resource Management
forming the scheduling and supervision backbone. An efficient job queue can be written using ZIO constructs using
surprisingly minimal amount of code.
Realtime push-based databases such as Google Firebase conveniently ensure
clients are synchronized with the server. Data updates stream to clients immediately as they happen; and if a client
disconnects, updates are immediately processed after reconnecting.
gRPC server streaming
and ZIO Hub can implement this functionality replicating an expensive paid
Firebase service while allowing greater extensibility.
Streaming is the primary mechanism to reduce memory requirements for processing large datasets. The approach is to
view only a small window of data at a time, allowing data to stream through in manageable amounts matching the
data window size to the amount of RAM available. A practical example is a file-upload, where multi-GBs file streams
can be handled by MBs of server RAM. However, enforcing streaming in software code is prone to errors, and misuse or
incompatible method implementations will lead to breaking stream semantics, and ultimately to OOM exceptions. This
article focuses on streams within the context of file uploads, using the Http4s library for examples.
Scala Native is a compiler and JDK written in Scala with the goal of removing Scala’s dependency on the JVM. This isn’t
meant to achieve a higher performance such as with JDKs, and it is targeting a specialized use-case not considered to be
today’s typical Scala development. Its competitors are Rust and Go, not GraalVM, Java or Kotlin. This article goes
through common steps and challenges encountered when compiling Scala Native for linux with a GitHub Action.
The free tier of GitHub Packages has limited bandwidth to download private artifacts; which can make it unsuitable for
use in a CI/CD pipeline for projects on a budget. In an effort to increase GitHub Packages’ usability, this article
develops an alternative approach minimizing the dependency on GitHub Packages as hot storage, but preserving it as a
viable cold storage, durable storage solution.
In-memory caches mapping Key => Value are a simple and versatile tool to reduce number of calls to an origin
datasource. There are many use-cases requiring multiple cache calls, preferring Seq[Key] => Seq[Value]. Can a standard
cache implementation be expanded to efficiently handle this scenario?
Modern software design requires the understanding of the different layers of concurrency and parallelism that can exist.
Abstractions exposed by libraries and frameworks can inadvertently hide layers of parallelism when their focus is the
simplification of others; and libraries trying to treat all levels of parallelism equality can be limited to low level
concepts for their common interface. In order to optimally design and avoid errors, all levels of concurrency and
parallelism need to be understood no matter what framework is chosen.
Scala is slow to compile.
Advanced syntax constructs and a robust type system can increase developer productivity and runtime reliability but also
create extra work for the compiler. Macro libraries such as Quill are effectively programs
written for the compiler, and can represent an unbounded amount of work depending on what they are trying to accomplish.
Are there ways to structure our Scala 3 code to ensure that we can embrace the rich macro ecosystem without excessively long compile times?
Akka / Apache Pekko is a robust and popular Scala framework used to build concurrent
production-grade software. One of the concurrency primitives it uses is the standard scala.concurrent.Future class.
Before these existed in Scala, there was
the Twitter Future offering similar, but expanded
functionality including cancellation / interruptibility. Ignoring the functional coding style promoted
by ZIO for a second, the concurrency primitive used by ZIO, known as ZIO[R, E, A] can be viewed as
a more advanced Future[A].
The Electric Frontier Foundation (EFF) has recommendations
about encrypting the web; there is no reason to be
running servers over unencrypted HTTP any longer. It is irresponsible to your users and unnecessary, as such there is a
formal mechanism called HTTP Strict Transport Security (HSTS) that
enforces HTTPS for all requests at the domain level. Taking it further, modern browsers include a set of domains which
can only work over HTTPS, it started with Google TLDs such as .dev and .app, but it is
growing https://hstspreload.org/.
The release of the Trade Audit mobile app is almost here. It is currently in MVP stage, but
its infrastructure is a pretty typical cloud based deployment. This article discusses design choices made, evaluating
how effective they were.
SVG markup is very similar to HTML, and the Lit Web Components library can be used to not only
generate HTML custom components, but also manipulate SVG in a similar way using Lit templates. Lit is a small 5kb
library that removes the boilerplate code of DOM generation, and is highly interoperable with all web frameworks since
it relies on browser native custom elements.
GitHub Pages is free hosting for static content webpages, and a cost-effective way to publish microsites for all of
your projects. Can it handle custom domains, and HSTS domains? How about multiple custom HSTS domains?
The suitability of programming languages across different domains is a contested topic. AWS Lambda Functions are a
serverless solution that can be used for a wide range of problems from tiny to large tasks. For lightweight tasks how
does the JVM stack up?
AWS Lambda offer the ability to run code functions without a server. Basically standalone functions that receive JSON as
a parameter and have up to 15 minutes to do anything. The source of the JSON event can be anything, AWS has configured
most of their AWS products to emit events; for example uploading a file to S3 creates JSON that contains information
about the file. Lambdas are meant to be simple and short-lived code snippets, so each Lambda can only listen to 1 source
for events (although you can proxy multiple types of events through a single source). The most generic source for events
is to listen to HTTP requests on a public URL, and we’ll cover how that can be done in this article.
GitHub Packages is a Maven compatible repository accessible outside of GitHub. It serves as the code repository used in
Java project compilation both on workstations and within a CI/CD pipeline, as well as allowing manual file downloads
through the GitHub web interface. Because it is meant for only these 2 purposes there is no REST API available making
custom integrations more difficult than need be. This article documents the URLs exposed through Maven which can be
used to create an API of simple HTTP commands. URLs to browse packages and download files will be covered, as well as
steps to more effectively use free tier resources allowed on private repositories.
GitHub Packages is a natural extension of a CI/CD pipeline created in GitHub Action. It currently offers repositories
for Java (Maven), .Net (NuGet), Ruby (Gems), JavaScript (npm), and Docker images.
For a lot of users this can be a free private service if you can squeeze under the size limitation and are okay using
OAuth keys managed in GitHub.
The command line progress bar was the first step towards graphical UI. It was an exciting addition to a numerical
percent ticking away as a running task took forever to complete. It started with safe for everywhere ascii characters
Over time there has been an ebb and flow to the ratio of JavaScript:HTML used in websites. What motivates the change,
and where is this ratio ultimately headed?
The Reactive Manifesto puts together the ideal architecture for today’s system
infrastructure, designed to cope with ever-increasing need for performance, reliability and responsiveness. The same
evolution of expectations is taking place in the JavaScript front-end, but do the same ideas and principles apply?
HTML elements are free
to change the style, size, and placement of their children, and even their order. A lot of advanced use cases define
rendering based on both the properties of element as well as the properties of their children; one particularly
interesting case is the 2 column timeline. This is similar to a standard 2 column flow, except instead of first filling
one column and overflowing to the second, columns are filled simultaneously – inserting elements into whichever has the
least content. The net effect is elements occurring earlier in the HTML markup are placed vertically higher in the page
than elements occurring later. The page reads top to bottom as a chronological timeline, which while being a simple
enough concept cannot be done using standard HTML. In fact, the exact ordering of elements are different based on widths
of the columns. Column placements are determined by previous element’s heights, and heights are a function of widths, so
setting colum...
Thread-Local storage (TLS)
allows static variables to be attached to the currently executing thread. The most common use of TLS is to allow global
context to be available throughout the entire call stack without passing it explicitly as a method parameters. In a
web-application, this allows contextual request metadata, such as the URL, to be referenced anywhere within the code
handing the request; which is extremely useful for logging or auditing purposes.
Most sortable HTML
table generators (such as AngularJS’s ng-grid) allow cells to be customized and
formatted according to templates, however all templates are specified as parsed strings of HTML content. The Web
Components specification allows for HTML Templates, meaning
actual HTML fragments can be used instead of pieced together strings. Two benefits are better readability, CSS
encapsulation by way of Shadow DOM, and soon to be native
support by modern browsers.
As businesses now rely
more heavily on web applications to perform daily operations, a user-friendly datatable/spreadsheet is indispensable to
all web developers. While individual requirements vary, the core staple is the sortable table. Using Polymer’s Templates
and Data-Binding, one can be implemented in a remarkably concise way.
One useful feature of
modern JavaScript libraries is 2-way data-binding. All interactive websites perform this functionality one way or
another, but only a few libraries such as Ember.js, AngularJS
and Polymer don’t require a single line of JavaScript.
In the years 2002-2003, Internet Explorer captured 95% of world-wide browser market share. It was unfathomable to many
that over the next 10 years IE would decline to just over 15%.
At the heart of a web
page, there are UI elements and these elements interact: with the user, each other, and the server.
Although HTML5 expanded the original set of elements to include audio,
video, and date pickers, there has been no standard way to define custom elements. Elements not specified in the HTML
specification have had no support thrusting this responsibility onto client-side and server-side web frameworks.
The key to high availability is
redundancy; it follows that if uptime matters, Finagle needs to be deployed to
multiple servers. This article walks through both the basic multi-host configuration using finagle-core, and a
more robust deployment scenario utilizing the finagle-serversets module.
The Separation of Concerns (SoC) pattern is one of those software
architectural choices that everyone is helpful. It increases clarity, shortens the amount of code in the working
context, and minimizes the chance of side effects. For example, two concerns that should not require entanglement:
updating data and cache invalidation. Both are related, but one is concerned about business logic and database access,
while the other deals with the cache servers. Finagle’s generated FutureIface can be used to keep these two separate.
A 30-minute presentation on Sept 19th at the Scala-Toronto Meetup. The
slides introduce a technical application of Apache Thrift and additional features offered by
the Twitter Finagle.
Long-running queries are very taxing on a database because they hold on to resources making them unavailable to other
requests. And what happens if multiple identical requests are made while one is still running? Is there a natural way
to share the same result, or do each request need to perform their own? This isn’t a simple caching solution, it’s
more like a subscription behaviour to a running query if one already exists, if not one is created.
In a Service Oriented Architecture, a service may be used by many different clients – each with different usage
patterns and performance profiles. Behind a corporate firewall, without each client authenticating itself to our server,
how can monitor a specific client if we can’t identify their requests?
One of the largest headaches associated with network system architecture is abstracting away the network. External
resources are always slower and more disjoint than working locally. While there are various caching techniques, few are
suitable for use in a development environment.
When using Thrift, Finagle Filters on the client inherit from SimpleFilter[ThriftClientRequest, Array[Byte]], while on
the server they must inherit from SimpleFilter[Array[Byte], Array[Byte]]. In this article, we will demonstrate one
approach to creating a dual-function filter without repeating code.
For many data services, any easy way to reduce database load is to cache calls to semi-static data (ie: append-only, or
refreshed only on a set schedule), and very recent calls due to backward user navigation. Not all methods and data are
suitable for caching, so any implementation will require the ability to be selective.
In a system of async service calls, sometimes the most indispensable debugging tool is knowing what and when network
traffic is occurring. Unfortunately for developers Finagle’s default protocol is binary, which while undecipherable, it
can be transformed into something a lot more useful.
Ostrich is a stats collector and reporter created by Twitter, and it is a welcome addition to
any Finagle (Apache Thrift) implementation. At its
core it uses an extremely lightweight com.sun.net.httpserver.HttpServer to handle JSON and HTML requests.
Apache Thrift is a pretty
good RPC library. Methods compose a service, and the service is
hosted on a raw TCP port. Even a large implementation with a hundred methods will perform effortlessly, but for
organizational purposes you’ll want to group calls together into separate services. The standard thrift protocols
require that each service retain exclusive use to its own TCP port, creating a firewall maintenance nightmare.