Friday, December 29, 2017

How to Create a Preset in Adobe Lightroom in 60 Seconds

How to Create a 3D Marquee Bulb Sign Text Effect in Adobe Photoshop

Create a Material Design Tabbed Interface in an Android App

The Best Free Online Presentation Software Tools for 2018

Get Started With Firebase Storage for iOS

New Course: Branding on a Budget With Elements and Affinity

How to Send Emails in Laravel

How to Send Emails in Laravel

In this article, we're going to explore the Mail API in the Laravel web framework. Laravel takes advantage of the popular SwiftMailer library, which is easy to use and comes with a variety of email drivers to choose from. In the latter stages of the article, we'll go through an in-depth demonstration of the concepts discussed in the first half of the article.

Setting Up the Prerequisites

Laravel implements a wrapper on top of the SwiftMailer library that makes email management very easy to configure and use at the same time. You can find the default mail settings at config/mail.php.

When it comes to sending mails, Laravel supports different drivers to choose from. As you can see, the default MAIL_DRIVER is set to smtp.

If you are going to use the smtp driver to send mails then you're also required to set other related settings like MAIL_HOST, MAIL_PORT, MAIL_ENCRYPTION, MAIL_USERNAME, and MAIL_PASSWORD.

On the other hand, if you are going to use the sendmail driver, then you want to make sure that the sendmail system path is set to the correct value in the config/mail.php file.

You can also set the from address that will be used while sending mails under the from key. And finally, if you want to use Markdown-based email rendering, you can set those settings under the markdown key.

The cherry on the top is that you could also use third-party email service providers like Mailgun, Mandrill, SES, and SparkPost. If you are using one of those services, you need to make sure that you set the corresponding settings in the config/services.php file.

So that was a basic introduction to the mail API related settings in Laravel. From the next section onwards, we'll go through a custom example that shows you how to send emails.

Create the Mailable Class

In this section, we'll create the mailable class, which will be used to send emails. The mailable class is responsible for sending emails using a mailer that's configured in the config/mail.php file. In fact, Laravel already provides an artisan command that allows us to create a base template.

That should create a blank email template at app/Mail/DemoEmail.php, as shown in the following snippet.

Let's replace the contents of that file with the following.

There are two important methods the mailable class generally implements—__construct and build. The __construct method is used to initialize objects that you're supposed to use in the email template. On the other hand, the build method is used to initialize more email-specific values like from, view template, attachments and similar.

In our case, we've passed the $demo object as a constructor argument, and it's assigned to the demo public property.

In the build method, we've initialized an email-specific configuration.

  • The from is used to set an email address that'll be used as a from address.
  • Using the view method, you can set the email template that will be used while sending an email using this mailable. In our case, we've set it to mails.demo, and it means that you need to create a view template file at resources/views/mails/demo.blade.php.
  • Next, the text method is used to set up the plain text version of an email template.
  • As we've just discussed, the __construct method is used to set up objects that'll be used in the email template, you can also use the with method that allows you to set the view data of a message.
  • Next, we've used the attach method to attach an image with a message.

Of course, we need to create email templates that we're supposed to use while sending emails. Go ahead and create a file resources/views/mails/demo.blade.php as shown in the following snippet.

Also, let's create the plain text version of that file at resources/views/mails/demo_plain.blade.php.

So that was the mailable class at your disposal, and we've not done yet as we need to use the Mail facade to actually send mails. In the very next section, we'll explore how you can use the Mail Facade to send emails using the DemoEmail Mailable class that was just created in this section.

Wrapping Up

In this section, we'll create an example to demonstrate how you can use the Mailable class that was created in the last section.

Let's create a controller file at app/Http/Controllers/MailController.php with the following contents.

It's important to note that we've included the Illuminate\Support\Facades\Mail Facade that will be used to send an email. In the send method, the following statement is responsible for sending an email by initialising the App\Mail\DemoEmail Mailable in the first place.

The to method of the Illuminate\Support\Facades\Mail Facade returns an instance of the \Illuminate\Mail\PendingMail class, which already contains an appropriate mailer configured in the config/mail.php file.

And finally, we use the send method of the \Illuminate\Mail\PendingMail class that sends an actual email.

To test it, let's add an associated route in the routes/web.php file.

And with that in place, you can run the http://ift.tt/2BSrKyg URL to see if it works as expected.

On the other hand, if you want to test your email templates quickly, without sending actual emails, there's a provision in Laravel that allows you to log all outgoing emails.

To achieve that, you need to set the value of MAIL_DRIVER to log in the config/mail.php file. Next, you could run the aforementioned URL and inspect the log file to check if the email template was logged there.

If everything goes fine, you should see an email being logged to the storage/logs/laravel.log file.

That's pretty much it as far as the mail feature is concerned in Laravel, and that concludes this article as well.

Conclusion

Today, we went through the mail API that comes built into Laravel, and it also supports a variety of drivers as well.

Starting with basic concepts, we implemented the mailable class that is an essential element in the mail API in Laravel as we moved on. At the end, we also tested the mailable class by creating a custom controller to see if it actually works.

If you're just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study in Envato Market.

I would love to know your feedback in the form of queries and comments using the feed below!


Working With Files in Keyboard Maestro: Part 2

How to Create a Mock Haynes Manual Cover in Adobe InDesign

Thursday, December 28, 2017

How to Edit a Documentary Interview Video

10 Easy Photo Slideshow Templates for Adobe After Effects

How to Create a Cartoon Polar Bear Portrait in Adobe Illustrator

How to Make Your First eCommerce Website With WordPress

10 Best PHP Instagram Scripts & Widgets

How Artificial Intelligence is Becoming Part of UX Design

Understanding Particles and Dynamics in Maya—Part 14

Learn Colored Pencil Techniques and How to Create a Trio of Flowers

Tuesday, December 26, 2017

2 Ways to Create an Animated Particle Background

Photoshop in 60 Seconds: Brush Panel—A Look at the New 2018 Update

New Course: Get Started With Augmented Reality for iOS

Components in Vue.js

Components in Vue.js

Introduction

Vue.js components are important to understand as you work with Vue.js. In this tutorial we are going to dig into Vue.js components, understanding the basics and applying them to an application. Let's get started.

What Are Components?

Components enable us to break the complexity of an application into tiny chunks. For example, a typical web application will have sections like header, sidebar, content, and footer.

Vue.js allows us to break each of these sections into separate modular code called components. These components can be extended, and then attached to the application you are working on. Components are a great way of reusing your code throughout your application.

Let's say you have a blog application, and you would like to display a list of blog posts. Using a Vue component, you can do:

Vue handles the rest.

Create a simple HTML page that mounts a Vue instance to your DOM element. You will use this to learn about components. Here is what the sample HTML page should look like:

In the above, you created a simple Vue instance, with no component factor in the code. Now if you want the welcome message to appear twice, how do you do it? Try getting that to work.

Your guess might be to have the div where the Vue instance is mounted appear twice. That will not work. Try changing it from id to class so you have this:

It still will not work!

The only way to get around this is to create a component. How do you create a component?

Components are created using the Vue.component() constructor. This constructor takes two parameters: the name of your component (which can also be called the tag name), and an object containing options for your component.

Let's create a component using what you have above.

In the above, the component name is called welcome-message. Your component can have whatever name you choose. Yet it is important that the name does not interfere with any HTML tags, as you will not want to override it.

The options object passed to the constructor contains the data and template. When creating components, your data should be a function, as you can see above. The data being held should then be returned as an object.

In situations where there are no data to pass, you can pass only the template like so:

With that done, you can use your component in your application by calling it like a regular HTML element using the name you passed to the constructor. It is called like this: <welcome-message></welcome-message>.

To output the template more than once, you call the component as many times as you want—as I did below.

From the above, this will display the welcome message four times.

Store Data in Components

Above I mentioned that data has to be a function, and the information it holds has to be returned as an object. Why is it like that?

When returned data is not an object, the components that make use of that data share the same source: shared data. Thus a change in data for one component affects the other component. This is not the same when the data is returned as an object.

It is important to see how this works practically. First, let's see a situation where data is returned as an object.

Can you guess what is happening above?

There are two components, and both components share the same data source as the data is not returned as an object. How do you prove I am right? When you view the above page from your browser, you will see that a change in one component results in a change in the data of the other component. How is it supposed to be?

Like this:

Here the data is returned as an object, and a change in one component does not affect the other. The function is executed for the individual component. When building your applications, it is important you do not forget this.

Creating and Using Components

Using the lessons learned thus far, let us implement this in a new Vue.js project started from scratch using vue-cli. If you do not have vue-cli installed on your machine, you can do that by running:

Start your new Vue.js project:

Navigate to your application, install the dependencies, and run your dev server using the commands below.

First, you'll rename the HelloWorld component that was created when you initialized your application to Hello.vue. You'll then register this component as a global component to be used in your application.

So your Hello component should look like this.

Nothing serious is happening here. You have your welcome text displaying the welcome message and a name which is passed as data. When the button underneath the welcome message gets clicked, the changeName method is called. This changes the name from Henry to Mark.

To use this component globally it has to be registered. Can you guess where that will be done? If you said main.js, you are absolutely correct.

To register a component, you import it and then use the Vue.component() constructor to set it up. Try that on your own.

I bet you got that to work. Here is how things should look in your main.js file.

Nothing new here except the line that imports your Hello component. The component is then registered using the constructor. Finally, for this part, the component needs to be displayed using the component name you entered. In this case, the component is display-name. This will be done in your App.vue file.

Open up src/App.vue and make it look like this.

With your server on, point your browser to http://localhost:8080. Click on the button and the name should change.

Let's see how to use a component locally.

Create a file called Detail.vue in your components directory. This component will not do anything special—it will be used in the Hello component.

Make your Detail.vue file look like this.

To use it in the Hello component, you start by importing it, as you did with the Hello component. Next, you register it, but this time you will not make use of the Vue.component() constructor.

You register it using the components object inside your exports. The name of the component which will be used as the element tag has to be passed as a value to the object. With that done, you can now use the element tag to output the component.

To understand all that, here is how the Hello component should look.

Refresh your page to see the new page.

Scoping Component Styles

Vue.js allows you to give global and local styling for your components. What do I mean? There might be scenarios where you want certain elements in a component to be styled differently from their counterparts in another component. Vue.js has got you covered on that.

A good example is available in the little app you just built. The styles in your App.vue are global; how is that possible? Open your App.vue, and the style section looks like this.

This is different from that of Detail.vue, which looks like this.

Adding scoped to the style tag makes all the difference. Try editing one of the component styles by removing scoped, and you will see how that works out.

Conclusion

That was a long one, and I trust you enjoyed it.

Now you know how to work effectively with components. You understand how to construct a component in an existing application. When working with vue-cli, you can also create and use components—locally and globally. When you want to use a particular style for a component, you saw how to do that using scoped.

You can now go on to build a complex Vue.js application that uses components. Understand that Vue.js allows you to reuse code—your headers, footer, login panel, and search bar can be used as components.


Create a Music Player App With Anko

Friday, December 22, 2017

5 Hot New Adobe After Effects Items, Christmas Video Edition

International Artist Feature: Venezuela

15+ Best eCommerce Website Templates: Updated for 2018

10 Best HR Software Solutions for Your Small Business (2018)

10 Best HTML5 Sliders for Images and Text

How to Create a Lego Batman Figurine in Adobe Illustrator

Working With Files in Keyboard Maestro: Part 1

Hot Shots: When a Laser Cuts Metal, Sparks Fly

Wednesday, December 20, 2017

How to Create a #Women2Drive Poster in Adobe Illustrator

60+ Time-Saving Print Templates for Adobe InDesign & Photoshop

Get Started With Natural Language Processing in iOS 11

Creating a Task Manager App Using Ionic: Part 2

How to Make Responsive WordPress Websites (With Themes)

Unity 2D Tile-Based Isometric and Hexagonal 'Sokoban' Game

5 Tips for Stakeholder “Buy-in”

5 Tips for Stakeholder “Buy-in”

UX designers don’t work alone; they need the support of their engineering or business counterparts. Here are some tips on how to smoothly navigate collaboration and get buy-in on your ideas! 

What is “Buy-in”?

If you Google “buy-in” you’ll most likely find that it’s a trading term, referring to the purchase of a controlling number of a company’s shares.

But that’s not what this article is about. We’re talking about people “buying into” an idea or concept. If a team member or stakeholder has “bought in”, then they agree with and accept your suggestions.

But how do we get buy-in?


1. Include Stakeholders in Early in the Process 

Including the major stakeholders into your design process early on sets the expectation that they are equal team members rather than gatekeepers. They may also bring a unique perspective to the constraints and edge cases that designers need to incorporate. 

Don’t neglect including partners early on in your product journey, as this is an excellent opportunity to educate them on the design process.

2. Speak to Tangible Ideas 

One advantage designers have is the ability to quickly make lo-fidelity mock-ups. A well-known adage is that “a picture is worth a thousand words”. This holds true for conversations where a team is in disagreement. 

Sketch out your ideas quickly rather than spending endless hours discussing them with hand-waving. Something tangible is easier to have conversations over and eventually test than words alone. Don’t spend time polishing your designs early on in the process when you should be exploring and iterating quickly. 

3. Have Empathy for Trade-offs 

When engaging your engineers, consider what implications your design options have for their time and resource investment. If what you are proposing is beyond the time they have to deliver, they will likely push back on your designs. Having a general sense of what takes more or less engineering efforts will allow you to speak to what is a priority in their minds. 

Note: This doesn’t mean to always cater to what is easiest to build–rather knowing what key experiences are worth the time investment as there are trade-offs to be made if resources are scarce. 

4. Convince With Data

When you aren’t able to convince your team of something you strongly believe is the right direction, bring data with customer evidence to support your point. 

Re-framing your point of view in terms of real users or business success is a value that most would prioritize above subjective opinions. 

5. Focus on the Problem 

When working in a team with many different personalities, it is easy to get caught up in the team dynamic and politics that distract from the project’s progress. Instead, focus back on the problem at hand. As a UX designer, your purpose is to bring a human-centered point of view to every problem you encounter. 

Conclusion

Make your ideas more tangible and test them with real users early and often. Then you can get feedback to iterate again–equipped with more knowledge, even with complex problems, information directs you toward making better design decisions that (hopefully) everyone can agree on. 


How to Create a Low Poly Tree in Cinema 4D

How to Create a Glazed Cookie Text Effect in Adobe Photoshop

How to Light for Interview Videos

Monday, December 18, 2017

60 Second How-to: Sync Image Settings in Adobe Photoshop Lightroom

How to Draw a Deer Step by Step

How to Create an Optimized Twitter Carousel Without AMP

Showing Material Design Dialogs in an Android App

Deferring Tasks in Laravel Using Queues

Deferring Tasks in Laravel Using Queues

In this article, we're going to explore the Queue API in the Laravel web framework. It allows you to defer resource-intensive tasks during script execution to enhance the overall end user experience. After introducing the basic terminology, I'll demonstrate it by implementing a real-world example.

Page load time is an important aspect of any successful website, and one should not overlook the importance of that as it affects the SEO of the site and the overall end user experience as well. More often than not, you end up needing to debug web pages with long page load times. Of course, there are different approaches you could use to rectify this issue.

Upon investigation, you often realize that there are certain code blocks causing a delay in the page execution. The next thing you could try is identifying blocks that can be deferred for processing and that have no real impact on the end result of the current page. That should really improve the overall web page speed as we've eliminated code blocks that were causing a delay.

Today, we're going to explore a similar concept in the context of the Laravel web framework. In fact, Laravel already provides a useful built-in API that allows us to defer the processing of tasks—the Queue API. Without wasting much of your time, I'll go ahead and discuss the basic elements of the Queue API.

Drivers, Connections, Queues, and Jobs

The basic purpose of the Queue API is to run jobs that are added in a queue. Next, the queue could belong to a specific connection, and that connection may belong to a specific queue driver configured with that connection itself. Let's briefly try to understand what I've just said.

Queue Drivers

In the same way you would have used a different driver for your database connection, you could also choose from a variety of different queue drivers. The Queue API supports different adapters like database, beanstalkd, sqs, and redis.

The queue driver is just a place that is used to store queue-related information. So if you're using a database queue driver, for example, the new job will be added in the jobs table in the database. On the other hand, if you've configured redis as the default queue driver, the job will be added to the redis server.

The Queue API also provides two special queue drivers for testing purposes—sync and null. The sync queue driver is used to execute a queue job immediately, while the null queue driver is used to skip a job so that it won't be executed at all.

Connections

When you configure the Queue API for the first time, you need to specify a default connection that should be used for default queue processing. At the very least, the connection is expected to provide the following information:

  • the queue driver that will be used
  • the queue driver's specific configuration values
  • the default queue name in which the job will be added

Queues

When you add any job into a queue, it'll be added into the default queue. In fact, that should be fine in most cases, unless you have jobs that need to be given higher priority over other jobs. In that case, you could create a queue named high and place the higher priority jobs in that particular queue.

When you run a queue worker that processes queued jobs, you could optionally pass the --queue parameter, which allows you to list queue names in the order in which they need to be processed. For example, if you specify --queue=high,default, it will first process jobs in the high queue, and once it's completed it fetches jobs in the default queue.

Jobs

A job in the Queue API is a task that's deferred from the main execution flow. For example, if you want to create a thumbnail when the user uploads an image from the front-end, you could create a new job that handles the thumbnail processing. In this way, you could defer the task of thumbnail processing from the main execution flow.

That was a basic introduction to the Queue API terminology. From the next section onwards, we'll explore how to create a custom queue job and run it by using a Laravel queue worker.

Create Your First Queue Job

By now, you should feel confident about queue jobs. From this section onwards, we're going to implement a real-world example that demonstrates the concept of queue jobs in Laravel.

More often than not, you end up in the situation where you need to create different thumbnail versions of an image uploaded by a user. In most cases, the developer tries to process it in real time so that different versions of images are created right away when the user uploads an image.

It seems to be a reasonable approach if you're going to create a couple of versions and it doesn't take too much time in the first place. On the other hand, if you're dealing with an application that requires heavy processing and thus eats up more resources, real-time processing could end up in a bad user experience.

The obvious option that pops up in your mind in the first place is to defer processing of the thumbnail generation as late as possible. The simplest approach you could implement in this specific scenario is to set a cron job that triggers processing at regular intervals, and you should be fine.

A much better approach, on the other hand, is to defer and push the task into a queue, and let the queue worker process it when it gets a chance to do so. In a production environment, the queue worker is a daemon script that's always running and processing tasks in a queue. The obvious benefit of this approach is a much better end user experience, and you don't have to wait for the cron run as the job will be processed as soon as possible.

I guess that's enough theory to get started with an actual implementation.

In our case, we're going to use the database queue driver, and it requires us to create the jobs table in the database. The jobs table holds all the jobs that need to be processed in the next queue worker run.

Before we go ahead and create the jobs table, let's change the default queue configuration from sync to database in the config/queue.php file.

In fact, Laravel already provides an artisan command that helps us to create the jobs table. Run the following command in the root of your Laravel application, and it should create the necessary database migration that creates the jobs table.

The migration file that's generated at database/migrations/YYYY_MM_DD_HHMMSS_create_jobs_table.php should look like this:

Next, let's run the migrate command so that it actually creates the jobs table in a database.

That's it as far as the jobs migration is concerned.

Next, let's create the Image model that will be used to manage images uploaded by the end user. The image model also requires an associated database table, so we'll use the --migrate option while creating the Image model.

The above command should create the Image model class and an associated database migration as well.

The Image model class should look like this:

And the database migration file should be created at database/migrations/YYYY_MM_DD_HHMMSS_create_images_table.php. We also want to store the original path of the image uploaded by the end user. Let's revise the code of the Image database migration file to look like the following.

As you can see, we've added the $table->string('org_path') column to store the path of the original image. Next, you just need to run the migrate command to actually create that table in the database.

And that's it as far as the Image model is concerned.

Next, let's create an actual queue job that's responsible for processing image thumbnails. For the thumbnail processing, we're going to use a very popular image processing library—Intervention Image.

To install the Intervention Image library, go ahead and run the following command at the root of your application.

Now, it's time to create the Job class, and we'll use an artisan command to do that.

That should create the Job class template at app/Jobs/ProcessImageThumbnails.php. Let's replace the contents of that file with the following.

When the queue worker starts processing any job, it looks for the handle method. So it's the handle method that holds the main logic of your job.

In our case, we need to create a thumbnail of an image uploaded by the user. The code of the handle method is pretty straightforward—we retrieve an image from the ImageModel model and create a thumbnail using the Intervention Image library. Of course, we need to pass the corresponding Image model when we dispatch our job, and we'll see it in a moment.

To test our newly created job, we'll create a simple upload form that allows the user to upload an image. Of course, we won't create image thumbnails right away; we'll defer that task so that it could be processed by the queue worker.

Let's create a controller file at app/Http/Controllers/ImageController.php as shown below.

Let's create an associated view file at resources/views/upload_form.blade.php.

Finally, let's add routes for the index and upload actions in the routes/web.php file.

In the ImageController controller, the index method is used to render an upload form.

When the user submits a form, the upload method is invoked.

At the beginning of the upload method, you'll notice the usual file upload code that moves the uploaded file to the public/images directory. Next, we insert a database record using the App/Image model.

Finally, we use the ProcessImageThumbnails job to defer the thumbnail processing task. It's important to note that it's the dispatch method that's used to defer a task. At the end, the user is redirected to the upload page with a success message.

At this point in time, the job is added to the jobs table for processing. Let's confirm it by issuing the following query.

You must be wondering, what does it take to process a job then? Don't worry—that's what we're going to discuss in the very next section.

Queue Worker

The job of the Laravel queue worker is to process jobs that are queued up for processing. In fact, there's an artisan command that helps us to start the queue worker process.

As soon as you run that command, it processes pending jobs. In our case, it should process the ProcessImageThumbnails job that was queued up when the user uploaded an image earlier.

You would have noticed that when you start a queue worker, it keeps running until you kill it manually or close the terminal. In fact, it's waiting for the next job to be processed. As soon as there's a new job in the queue, it'll be processed right away if the queue worker is running.

Of course, we can't keep it running that way, so we need to find a way for the queue worker to run permanently in the background.

To our rescue, there are several process management tools out there you could choose from. To name a few, here's a list:

  • Circus
  • daemontools
  • Monit
  • Supervisor
  • Upstart

You should choose a tool that you're comfortable with to manage the Laravel queue worker. Basically, we want to make sure that the queue worker should run indefinitely so that it processes queued jobs right away.

So that's the Queue API at your disposal. You can use it in your day-to-day development to defer time-consuming tasks for the betterment of the end user experience.

Conclusion

In this article, we discussed the Queue API in Laravel, which is really helpful should you wish to defer processing of resource-consuming tasks.

We started with a basic introduction to the Queue API, which involved a discussion of connections, queues, and jobs. In the second half of the article, we created a custom queue job that demonstrated how you could use the Queue API in the real world.

For those of you who are either just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study in Envato Market.

Feel free to use the feedback form below to post your queries and suggestions.


How to Superscript Text in PowerPoint in 60 Seconds

Spirit App: Easy Realtime Animation For the Web

Introduction to Forms in Angular 4: Template-Driven Forms

How to Create a Sparkling Action in Adobe Photoshop

How to Draw a Festive Theatre Stage in Adobe Illustrator

Friday, December 15, 2017

10 Easy Pieces: Top Football Video Templates for Adobe After Effects

Envato Tuts+ Community Challenge: Created by You, December 2017 Edition

Testing Data-Intensive Code With Go, Part 5

Testing Data-Intensive Code With Go, Part 5

Overview

This is part five out of five in a tutorial series on testing data-intensive code. In part four, I covered remote data stores, using shared test databases, using production data snapshots, and generating your own test data. In this tutorial, I'll go over fuzz testing, testing your cache, testing data integrity, testing idempotency, and missing data.

Fuzz Testing

The idea of fuzz testing is to overwhelm the system with lots of random input. Instead of trying to think of input that will cover all cases, which can be difficult and/or very labor intensive, you let chance do it for you. It is conceptually similar to random data generation, but the intention here is to generate random or semi-random inputs rather than persistent data.

When Is Fuzz Testing Useful?

Fuzz testing is useful in particular for finding security and performance problems when unexpected inputs cause crashes or memory leaks. But it can also help ensure that all invalid inputs are detected early and are rejected properly by the system.

Consider, for example, input that comes in the form of deeply nested JSON documents (very common in web APIs). Trying to generate manually a comprehensive list of test cases is both error-prone and a lot of work. But fuzz testing is the perfect technique.

Using Fuzz Testing 

There are several libraries you can use for fuzz testing. My favorite is gofuzz from Google. Here is a simple example that automatically generates 200 unique objects of a struct with several fields, including a nested struct.  

Testing Your Cache

Pretty much every complex system that deals with a lot of data has a cache, or more likely several levels of hierarchical caches. As the saying goes, there are only two difficult things in computer science: naming things, cache invalidation, and off by one errors.

Jokes aside, managing your caching strategy and implementation can complicate your data access but have a tremendous impact on your data access cost and performance. Testing your cache can't be done from the outside because your interface hides where the data comes from, and the cache mechanism is an implementation detail.

Let's see how to test the cache behavior of the Songify hybrid data layer.

Cache Hits and Misses

Caches live and die by their hit/miss performance. The basic functionality of a cache is that if requested data is available in the cache (a hit) then it will be fetched from the cache and not from the primary data store. In the original design of the HybridDataLayer, the cache access was done through private methods.

Go visibility rules make it impossible to call them directly or replace them from another package. To enable cache testing, I'll change those methods to public functions. This is fine because the actual application code operates through the DataLayer interface, which doesn't expose those methods.

The test code, however, will be able to replace these public functions as needed. First, let's add a method to get access to the Redis client, so we can manipulate the cache:

Next I'll change the getSongByUser_DB() methods to a public function variable. Now, in the test, I can replace the GetSongsByUser_DB() variable with a function that keeps track of how many times it was called and then forwards it to the original function. That allows us to verify if a call to GetSongsByUser() fetched the songs from the cache or from the DB. 

Let's break it down piece by piece. First, we get the data layer (that also clears the DB and redis), create a user, and add a song. The AddSong() method also populates redis. 

This is the cool part. I keep the original function and define a new instrumented function that increments the local callCount variable (it's all in a closure) and calls the original function. Then, I assign the instrumented function to the variable GetSongsByUser_DB. From now on, every call by the hybrid data layer to GetSongsByUser_DB() will go to the instrumented function.     

At this point, we're ready to actually test the cache operation. First, the test calls the GetSongsByUser() of the SongManager that forwards it to the hybrid data layer. The cache is supposed to be populated for this user we just added. So the expected result is that our instrumented function will not be called, and the callCount will remain at zero.

The last test case is to ensure that if the user's data is not in the cache, it will be fetched properly from the DB. The test accomplishes it by flushing Redis (clearing all its data) and making another call to GetSongsByUser(). This time, the instrumented function will be called, and the test verifies that the callCount is equal to 1. Finally, the original GetSongsByUser_DB() function is restored.

Cache Invalidation

Our cache is very basic and doesn't do any invalidation. This works pretty well as long as all songs are added through the AddSong() method that takes care of updating Redis. If we add more operations like removing songs or deleting users then these operations should take care of updating Redis accordingly.

This very simple cache will work even if we have a distributed system where multiple independent machines can run our Songify service—as long as all the instances work with the same DB and Redis instances.

However, if the DB and cache can get out of sync due to maintenance operations or other tools and applications changing our data then we need to come up with an invalidation and refresh policy for the cache. It can be tested using the same techniques—replace target functions or directly access the DB and Redis in your test to verify the state.

LRU Caches

Usually, you can't just let the cache grow infinitely. A common scheme to keep the most useful data in the cache is LRU caches (least recently used). The oldest data gets bumped from the cache when it reaches capacity.

Testing it involves setting the capacity to a relatively small number during the test, exceeding the capacity, and ensuring that the oldest data is not in the cache anymore and accessing it requires DB access. 

Testing Your Data Integrity

Your system is only as good as your data integrity. If you have corrupted data or missing data then you're in bad shape. In real-world systems, it's difficult to maintain perfect data integrity. Schema and formats change, data is ingested through channels that might not check for all the constraints, bugs let in bad data, admins attempt manual fixes, backups and restores might be unreliable.

Given this harsh reality, you should test your system's data integrity. Testing data integrity is different than regular automated tests after each code change. The reason is that data can go bad even if the code didn't change. You definitely want to run data integrity checks after code changes that might alter data storage or representation, but also run them periodically.

Testing Constraints

Constraints are the foundation of your data modeling. If you use a relational DB then you can define some constraints at the SQL level and let the DB enforce them. Nullness, length of text fields, uniqueness and 1-N relationships can be defined easily. But SQL can't check all the constraints.

For example, in Desongcious, there is a N-N relationship between users and songs. Each song must be associated with at least one user. There is no good way to enforce this in SQL (well, you can have a foreign key from song to user and have the song point to one of the users associated with it). Another constraint may be that each user may have at most 500 songs. Again, there is no way to represent it in SQL. If you use NoSQL data stores then usually there is even less support for declaring and validating constraints at the data store level.

That leaves you with a couple of options:

  • Ensure that access to data goes only through vetted interfaces and tools that enforce all the constraints.
  • Periodically scan your data, hunt constraint violations, and fix them.    

Testing Idempotency

Idempotency means that performing the same operation multiple times in a row will have the same effect as performing it once. 

For example, setting the variable x to 5 is idempotent. You can set x to 5 one time or a million times. It will still be 5. However, incrementing X by 1 is not idempotent. Every consecutive increment changes its value. Idempotency is a very desirable property in distributed systems with temporary network partitions and recovery protocols that retry sending a message multiple times if there is no immediate response.

If you design idempotency into your data access code, you should test it. This is typically very easy. For each idempotent operation you extend to perform the operation twice or more in a row and verify there are no errors and the state remains the same.   

Note that idempotent design may sometimes hide errors. Consider deleting a record from a DB. It is an idempotent operation. After you delete a record, the record doesn't exist in the system anymore, and trying to delete it again will not bring it back. That means that trying to delete a non-existent record is a valid operation. But it might mask the fact that the wrong record key was passed by the caller. If you return an error message then it's not idempotent.    

Testing Data Migrations

Data migrations can be very risky operations. Sometimes you run a script over all your data or critical parts of your data and perform some serious surgery. You should be ready with plan B in case something goes wrong (e.g. go back to the original data and figure out what went wrong).

In many cases, data migration can be a slow and costly operation that may require two systems side by side for the duration of the migration. I participated in several data migrations that took several days or even weeks. When facing a massive data migration, it's worth it to invest the time and test the migration itself on a small (but representative) subset of your data and then verify that the newly migrated data is valid and the system can work with it. 

Testing Missing Data

Missing data is an interesting problem. Sometimes missing data will violate your data integrity (e.g. a song whose user is missing), and sometimes it's just missing (e.g. someone removes a user and all their songs).

If the missing data causes a data integrity problem then you'll detect it in your data integrity tests. However, if some data is just missing then there is no easy way to detect it. If the data never made it into persistent storage then maybe there is a trace in the logs or other temporary stores.

Depending how much of a risk missing data is, you may write some tests that deliberately remove some data from your system and verify the system behaves as expected.

Conclusion

Testing data-intensive code requires deliberate planning and an understanding of your quality requirements. You can test at several levels of abstraction, and your choices will affect how thorough and comprehensive your tests are, how many aspects of your actual data layer you test, how fast your tests run, and how easy it is to modify your tests when the data layer changes.

There is no single correct answer. You need to find your sweet spot along the spectrum from super comprehensive, slow and labor-intensive tests to fast, lightweight tests.  


Manipulating HTML5 Canvas Using Konva: Part 5, Events

Manipulating HTML5 Canvas Using Konva: Part 5, Events

If you have been following this series from the beginning, you should now be very comfortable with shapes, groups, and layers. You should also be able to easily draw some basic and complex shapes on the canvas using Konva. If you plan on using Konva to create some interactive app or games, learning how to bind events to different shapes on the stage is the next logical step.

In this tutorial, you will learn how to bind events to any shape using Konva. You will also learn about event delegation and propagation. Sometimes, you need might need to control the hit region of a shape as well as fire events programmatically. We will be discussing these two topics as well.

Binding Events to a Shape

You can bind different events to any shape created using Konva with the help of the on() method. All you have to do is pass the name of the event as the first parameter and the function to be executed when the event occurs as the second parameter. You can use Konva to detect mouseup, mousedown, mouseenter, mouseleave, mouseover, mousemove, click, and dblclick. Additionally, Konva allows you to detect wheel, dragstart, dragmove, and dragend events.

Here is an example that detects mousedown and mouseleave events on a regular polygon (hexagon). Similarly, the smaller circle is bound to the mouseover and mouseup events and the larger circle is bound to the mouseenter, mouseleave, and mousemove events.

If a user presses any mouse button while the cursor is inside the regular polygon, we increase the number of sides of the polygon by 1. The sides() method can be used without a parameter to get the number of sides for a polygon or used with one parameter to set the number of sides for a polygon. You can also get the number of sides using getSides() and set the number of sides using setSides(). The sides of the polygon are reduced by one whenever the mouse cursor leaves the polygon.

For the smaller circle, the mouseover event is used to set the stroke width value to 10. The mouseup event changes the stroke width value to 5. Keep in mind that the mouseup event has to occur inside the circle itself. For example, the stroke width will not change to 5 if you press the mouse button inside the circle and then release it only after the cursor is outside the circle.

In the case of the larger circle, we are using the mousemove event to change its fill color. We are also changing the cursor of the larger circle using stage.container().style.cursor whenever the cursor moves in and out of the circle.

One important thing that you should keep in mind is that you have to call the draw() method on the respective layer if the event listeners for any shape resulted in a change of attributes like fill color, stroke width, etc. Otherwise, the changes won't be reflected on the canvas.

You don't have to bind one event at a time to a shape. You can also pass in a space delimited string containing multiple event types to the on() method. This will bind all the events listed in the string to that particular shape.

Konva also supports corresponding mobile versions of all these events. For example, you can register touchstart, touchmove, touchend, tap, dbltap, dragstart, dragmove, and dragend using Konva on mobile devices.

You can also fire any of these events for a particular shape or shapes using the fire() method. Similarly, Konva allows you to fire custom events like throwStones.

Removing Event Listeners

You can remove any event listeners attached to a shape with the help of the off() method in Konva. You just have to specify the event name that you don't want to listen to.

You can also create multiple event bindings for a single shape. For example, let's say you have a circle and you want to increase the radius of the circle every time the mouse cursor goes over it, up to a certain limit. You might also want to change the fill color of the circle on every mouseover event. 

One option is to do both these tasks inside a single mouseover event listener and stop updating the radius later. Another option is to create two mouseover event listeners with different namespaces to identify them. This way, you will be able to increase the radius and change the fill color independently.

You should note that I have added layerA.draw() inside both listeners. If you fail to add it inside the mouseover.fillcolor listener, the color will stop updating as soon as the radius becomes 150.

Instead of removing one event listener at a time, you can also stop listening to all events bound to a shape using the setListening() method. You can pass true and false to this method in order to turn event listeners on and off. Keep in mind that you will also have to redraw the hit graph of the affected layer by calling the drawHit() method right after you call setListening().

Event Delegation and Propagation

Instead of binding events directly to all the shapes present on a layer, you can also bind an event to the layer itself. After that, you can determine which shape triggered the event using the target property of the event object. This way, Konva allows you to effectively delegate events from the parent to its children.

Let's say you are listening to click events on a circle drawn on a layer in Konva. The same click event propagates to the containing group as well as the containing layer. This may or may not be the intended behavior. If you want to prevent the event from bubbling up inside a shape to the containing layer, you can set the cancelBubble property for the event object to true.

I have used the name property to assign a name to each of our shapes. The setText() method is then used to change the text inside textA to the name of the shape we just clicked.

Custom Hit Regions

In the above example, the ring registered a click on it when the click occurred between the inner and outer circle. What if you wanted to register the click inside the smaller circle as well? Konva allows you to define custom hit regions using the hitFunc property. This property accepts a function as its value, and this function is used to draw the custom hit region.

The following example shows you how to create custom hit regions. You should now be able to click in the area between the star spikes and still register a click. With the help of custom hit regions, you can make sure that your users don't have to click on exact locations to register a click event. This can result in a better user experience when dealing with smaller or more complex shapes.

Final Thoughts

In this tutorial, we have covered different mobile and desktop events that you can bind to any shape in Konva. You can attach these events one at a time or many of them at once. Konva also allows you to fire your own custom events programmatically using the fire() method. The last section of the tutorial showed you how to define your own hit regions in order to detect hits on an area that could be larger or smaller than the original shape.

Combining the knowledge of this tutorial with others in the series, you should now be able to draw a variety of shapes on the canvas and allow your users to interact with them. 

If you have any questions related to this tutorial, feel free to let me know in the comments.


How to Retrieve Your Deleted (Or Archived) Emails in Gmail

10 Best Android App Templates for Business

How to Create Three Star Wars Characters in Adobe Illustrator

Thursday, December 14, 2017

How to Add Lights to a Tree With a Photoshop Action

Good Sounds: How to Record an Interview Subject's Voice

Manipulating HTML5 Canvas Using Konva: Part 4, Styling

Manipulating HTML5 Canvas Using Konva: Part 4, Styling

In the second tutorial of the series, you learned how to draw some basic shapes like rectangles, circles, and regular polygons using Konva. The third tutorial covered how you can use Konva to draw some more complex shapes like stars and rings as well as sprites on the canvas.

In this tutorial, we will go one step further and learn how to apply different styling to shapes by changing their fill and stroke values. You will also learn how to control the opacity of a shape and apply shadows to it. In the final sections, you will learn how to use blend modes to specify what the final result should look like if different shapes overlap.

Applying Fill and Stroke

We have been using the fill and stroke properties from the first tutorial of the series. However, we have only used them to fill shapes with a solid color so far. You can also fill a shape with gradients (both linear and radial) as well as images. The same goes for different strokes applied to a shape.

There are two ways of applying a fill to different shapes. You can either set the fill value using the fill property when a shape is first created in Konva, or you can use the fill() method to apply a fill dynamically in response to some events like hover, button click, etc.

When filling an element with a solid color, you can specify a value for the fill property and it will work just fine. When using a linear gradient to fill the inside of a shape, you need to specify valid values for a lot of other properties like fillLinearGradientStartPointfillLinearGradientEndPoint, and fillLinearGradientColorStops. The first two properties accept objects that specify the x and y co-ordinates of the start and end points of a gradient. You can also specify the x and y values separately using the fillLinearGradientStartPointXfillLinearGradientStartPointYfillLinearGradientEndPointX, and fillLinearGradientEndPointY properties.

Radial gradients also have the same set of properties, but the word Linear is replaced with Radial. Two additional properties related to radial gradients are fillRadialGradientStartRadius and fillRadialGradientEndRadius.

When not specified, the start and end point of a radial gradient are assumed to be 0,0. This is why the radial gradient in the third rectangle originates from the top left corner. Also remember that the start and end points are specified relative to the shape itself.

Just like the fill, you can set a value for the stroke color and stroke width using the stroke and strokeWidth properties when a shape is first instantiated. You can also dynamically set both these values using the stroke() and strokewidth() methods.

Creating Shadows in Konva

You can apply shadows to any shapes created using Konva with the help of four different properties called shadowColor, shadowOffset, shadowBlur, and shadowOpacity. The shadowOffset property accepts an object with x and y components as its value, but you can also use shadowOffsetX and shadowOffsetY to specify the x and y co-ordinates separately. You also have the option of enabling and disabling the shadows for any particular shape using the shadowEnabled property.

You can control the opacity of the shape itself using the opacity property. Please note that a fully transparent object will not cast any shadow. Similarly, if you have set the fill color of a shape to transparent, only the shadow of its stroke will be rendered on the canvas.

Setting the shadowBlur property to 0 makes the shadow as sharp as the original shape itself. Setting this value too high will make the shadow lose the original shape; you will only see a dark patch on the canvas.

I would like to point out that you can also create text shadows with the same set of properties once you have instantiated a Konva.Text() object.

Applying Blend Modes

So far in the series, any overlap between shapes hid the bottom shape completely. The only way to keep the bottom shape visible was to make all the shapes over it partially transparent. 

Sometimes, you might want the final result after the overlap of different shapes to follow certain rules. For example, it is possible to only show the lighter or darker color in cases where the shapes overlap. 

Konva allows you to specify some values to determine how the colors of overlapping shapes should blend together using the globalCompositeOperation property. You can read the documentation on MDN to learn about the property and all its possible values in more detail.

In the following example, I have applied a different blend mode to each of the rectangles placed at the corner of the central rectangle.

The color of the top-left rectangle is rgb(0, 200, 100), and the color of the central rectangle is rgb(255, 100, 0). When the lighten blend mode is applied, the rgb components of both the colors are compared individually, and the higher values for each component are used to get the final color. In our case, the final color for the top-left corner becomes rgb(255, 200, 100).

When the darken blend mode is applied, the rgb components of both the colors are compared individually, and the lower values for each component are used to get the final color. In our case, the final color for the top-right corner becomes rgb(0, 100, 0).

When the hue blend mode is applied, the luma and chroma of the bottom color are combined with the hue of the top color. This is why the final color still remains green but gets lighter. When the xor blend mode is applied, the final color becomes transparent at all the places of overlap.

Final Thoughts

In this tutorial, we learned how to fill a shape with linear or radial gradients instead of solid colors. We also learned how to apply shadows to different shapes and make them partially transparent using the opacity property. The final section showed you how to use blend modes in order to change the final color after two shapes overlap.

If you have any questions related to this tutorial, please let me know in the comments. The next and final tutorial of the series will teach you how to bind events to different shapes in Konva.