Frontend Migration: A Journey Through Time and Space
By: Andy Maskiell
Over the course of several months, our team has worked through a sizable migration of frontend code from one codebase to another. This is our story.
Extracting Sessions from Interaction Data in Snowflake
By: Sam Schick
Extracting Sessions from Interaction Data in Snowflake Processing user interaction data into something useful can be challenging. On the Pluralsight Search team, we can see every interaction a learner has with our search engine, but these events are much more meaningful when considered in context. Learners don’t think about what they are trying to accomplish as isolated API calls, so if we want to understand their motivation we should look at sets of interactions bundled together into sessions.
Prevent Sleep With the Screen Wake Lock API
By: Jaime Farnan
Keep your screen from falling asleep with the Screen Wake Lock API
Become a Digital Detective With Application Monitoring
By: Michelle Sisti
An unexpected perk of keeping an eye on your application's stats is detecting anomalies that could be tied to malicious users. Let’s look at ways that your logging and monitoring setup can work double time for you and help you to catch users with ill-intent.
Synthwave Styling Data Visualizations in Python with Altair
By: John Walk
The dream of the '80s is alive in my new favorite Python visualization tool.
Nickname Generation with Recurrent Neural Networks with PyTorch
By: John Walk
Recurrent Neural Network architectures are a potent way to model and generate sequential data, especially for tasks like working with human language. Let's build one over individual characters to generate cheeky nicknames!
What is a Data Owner, Really?
By: Jenny Carlston
What does it mean to take ownership? There are a lot of different ways the term owner is used in our society and within our organization.
Data Processing with Dask
By: John Walk
It's remarkably easy to reach a point where our typical Python tools don't really scale suitably with our data in terms of processing time or memory usage. The Dask library joins the power of distributed computing with the flexibility of Python development for data science, with seamless integration to common Python data tools. Let's build a simple data pipeline for working with text data.
Scala: Cats Effect Ref
By: Jeff Lewis
Ref provides a mutable reference which is non-blocking, pure, and atomic.
Data Boundaries
By: Justin Hewlett
Modern applications increasingly interface with lots of external systems — third-party APIs, databases, message queues, etc. In some cases, we may have control over the shape of the data being transmitted, but in other cases we may be at the mercy of something else. If we're not careful, implementation details like the shape of the data and the naming of the fields can permeate throughout our code.
Python CLI Utilities with Poetry and Typer
By: John Walk
Python is exceptionally flexible as a scripting language - let's learn how to extend simple scripts into full-featured command line utilities.
Containerizing Blazor Apps
By: Jeremy Morgan
Blazor is a hot new front-end development framework from Microsoft. Since it contains two different hosting models, deploying them to a container can be different depending on the type.
Porting Flask to FastAPI for ML Model Serving
By: John Walk
Due to its simplicity, Flask is a very popular web framework for building REST APIs in Python - particularly for serving Machine Learning models. Here we'll learn how to migrate to the newer FastAPI framework to take advantage of advances in type checking & asynchronous programming.
Test-driven Development Fundamentals
By: Patrik Drean
Test-driven development (TDD) is a methodology that programmers use to produce higher quality code. The "typical" procedure of coding has always been code first, test second. TDD swaps this mindset by focusing on testing before the actual coding happens.
Taming Dynamic Data in TypeScript
By: Justin Hewlett
Fully utilizing static types, with all the safety they provide, can be a bit tricky when dealing with dynamic data — like JSON from an API call. Let's look at how to do this in TypeScript.
Avoiding Magic Numbers
By: Jeff Nuss
Magic numbers are an anti-pattern and should generally be avoided. What do I mean when I say magic number? I’m referring to using numbers directly in code as opposed to using a named constant. This can also apply to other data types and literals, especially strings. Why are they bad? They inhibit readability and refactorability.
Understanding JavaScript Prototypes
By: Jim Cooper
JavaScript Prototypes can be a mysterious thing, but once you understand them they’re not that complex. Let’s dive in to the seeming complexity and remove some of the mystery.
Code Smell: Too Much Edge Case Handling
By: Dustin McQuay
If half or more of your code is handling edge cases, can you restructure your logic such that you don't have so many edge cases?
Moving to .NET Core: HttpModules to Middleware
By: Neil Sorensen
With .NET Core, Microsoft introduced a new way to build pipeline behavior—middleware. Middleware solves many of the challenges with HttpModules, and makes building a custom request pipeline easy. Converting our custom behavior to middleware was fairly easy, but there were a few surprises waiting for us.
Different Types of Unit Tests
By: Jonathan Turner
There are lots of different types of tests. There are lots of different types of automated tests. In this post we'll talk about unit tests, specifically a few different types of unit tests and when you might want to use each.
On Beyond Frameworks: Architecting for a Changing Reality
By: Neil Sorensen
Before we get too technical in our look at migrating to .NET Core, however, let's take a moment to review the architectural choices we made before we tried to switch frameworks. A large part of the reason that we were able to migrate from .NET Framework so quickly was because we separated our application logic from the decisions made by the framework.
Temporary Development Environments
By: Parker Johansen
As a polygot programmer, I often find myself needing to write code in a language for which I don't have a development environment setup. Usually, this is for a small or short term project. When these situations arise, I use docker to avoid spending time setting up a full development environment that I may never use again.
.NET Core: The Good, the Bad, and the Ugly
By: Neil Sorensen
This past summer, we converted one of our production webservices from WebApi2 to .NET Core. In this first post, I'll summarize our findings about the platform itself - where it shines, where it falls down, and the little quirks that give it "character". We'll be following up with posts that address some of the technical hurdles we went through in converting our application, as well as some insights we gained when rolling our first application to production.
Destroy Your Development Environment
By: Dustin McQuay
Destroying your development environment frequently provides a forcing function to ensure that everything is automated, works and prevents manually created state from creeping into your data stores. In this post, I'll share the cost of not doing this as well as tips and code examples to set up your own development environment.
Testing HTTP Calls
By: Allan Stewart
Making HTTP calls to get resources or call APIs is a staple of software development. But if you do not properly abstract the request construction and response handling from the HTTP library that you use, it can be extremely difficult to test.
Getting Size and Position of an Element in React
By: Dustin McQuay
Getting the size and position of elements in React is not a great story. Each option I researched has at least one gotcha. I'll share the best options I came up with and explain pros and cons of each. First let's take a look at the basic way to get an element's size and position in React.
Testable Javascript: Pure Functions
By: Dustin McQuay
Favoring stateless functions and pushing I/O the edge of your application can make your code easier to test and reason about.
Running Node.js in Production
By: Tim Cash
Node.js is a runtime for javascript that requires asynchronous thinking.
Imagining a Smarter Pluralsight
By: Auggie Hudak
What does it mean to be a software engineer on a machine learning team?
Cryptographic Hashing Functions
By: Eric Andres
A hashing function is a one-way function that takes some input and returns a deterministic output. The output is often referred to as a digest, a hash code, or simply a hash.
Property-based TDD
By: Matt Baker
Property-based testing is a type of testing that uses randomly generated inputs to test an attribute or characteristic of the subject under test. You can contrast this with the more traditional example-based testing approach, where you provide specific test cases for your subject under test. Typically, TDD is done using example-based testing. What happens when we use property-based testing in a TDD workflow?
Modern Comments
By: Neil Sorensen
I recently read a blog post arguing that comments are an important part of code, and the people who claim otherwise are missing out. While I tend to fall on the opposite side of the argument, I would certainly agree that there is a time and a place where comments in code make sense. More interestingly, I realized that I haven't seen many explanations of why comments are sub-optimal, and when they are still important. So, in an effort to improve that situation, here's my take on the principles behind comments, and when those same principles are better served with different tools.
Forms of Temporal Coupling
By: Allan Stewart
Coupling is an important concept in software development because it limits the ability of software to change. Temporal coupling is a kind of coupling where code is dependent on time in some way. It is particularly insidious because it is hard to detect unless you know what you are looking for.
Patterns of an Eventually Consistent Bounded Context: Out of Band Healing
By: Matt Baker
When working in a distributed system, your overall system is comprised of discrete components which I will call "bounded contexts." Sometimes these bounded contexts have the need to be eventually consistent. In this article we will cover Out of Band Healing, a pattern that can be used to reduce temporal coupling when healing your server-side caches.
Using systemd-notify with nodejs
By: Dustin McQuay
Many teams at Pluralsight use systemd for application process management. When systemd starts a process, it needs to know if the process started successfully. The most simple way to do this is for systemd to wait for a bit after starting the process (perhaps 10 seconds) and simply check that the process is still running. Since you generally can't predict exactly how long your service will take to successfully start up, this is error prone. Furthermore, this method is slow. If you are doing synchronous restarts for a rolling deploy, this adds a lot of time.
API Categorization
By: Dave Adsit
APIs are an integral part of our distributed system here at Pluralsight. We use them to communicate between and within bounded contexts. One of our engineering team mottoes is "Be Explicit." To that end, we have a categorization system for the APIs we build and publish. This helps us know what the API is for and who should (and who shouldn't) be using it.
Immutable Objects in C#
By: Justin Hewlett
You may have heard about the benefits of immutable objects, especially from the functional programming crowd. But creating and working with immutable objects in a language like C# can be tricky.
Dogma, Pragmatism and the Rule of 3
By: Matt Baker
Perfectionism and pragmatism are often at odds. How do you strike a balance between doing the perfect thing and doing the right thing?
System Architecture: Messaging Business Events
By: Dave Adsit
When we started on our journey towards bounded contexts, we wanted to maintain the small-team, focused, feel that we had enjoyed with as a single team supporting a monolith. One strategy we adopted was to limit our dependencies between the teams and, by extension, the different bounded contexts. We did not want to introduce temporal runtime coupling between components developed by different teams because that would reduce the autonomy of these teams and limit our ability to develop the products that we wanted to develop in the ways we wanted to develop them.
Switching Databases
By: Allan Stewart
In the summer of 2014, Pluralsight suffered a significant outage when our primary database failed. After recovering from the immediate problem, we decided we should migrate to a completely different database to improve performance and availability. Though it took some time to complete, the transition was surprisingly simple thanks to a powerful pattern.
Removing Null from C#
By: Eric Andres
Null references can be a source of subtle bugs in software. Maybe is a tool that, while deceptively similar, provides much greater safety.
Password Security
By: Allan Stewart
In an era where password breaches are all too common, it's easy to be concerned about what companies do with user passwords. Unfortunately, in most cases it's a black-box scenario where we can only guess at what's going on under the hood based on clues like character or length restrictions.
System Architecture: Bounded Contexts
By: Dave Adsit
Microservices architectures are currently highly fashionable. The question of how small a microservice can be is asked regularly. Is micro even small enough? Can we build pico-services? At Pluralsight, we have chosen to go a different direction. We are focusing on team size...