Search

Codingbunny

A blog about coding, run by a bunny

First blog post

Blog under construction.

As I just returned from my business trip for the Euruko 2016, I just threw this online rather quick. Over the coming days I will tune this blog and write my first article based upon a problem I’m currently dealing with at work.

Advertisements
Featured post

Windows Desktop Drivers

The Problem

Most people have a Windows computer at home. And this thing comes with hardware. And hardware requires drivers in order to function properly. But how many people keep their drivers up to date? How many people actually install the correct drivers instead of the generic Microsoft ones?

Sure, your system will work with the Microsoft drivers, but when you’re into gaming, you want to have the correct drivers to ensure that your system is running with the best possible configuration.

Driver Easy

I’m normally not someone to promote tools or things, but Driver Easy is someone that caught my attention and is something I use regularly now to find that one missing driver in my system that causes a component to not work at the best possible performance. Having a high-end gaming system, this means often updating drivers to make sure everyone performs at peak-performance.

With the guide here, I want to demonstrate how you can keep your system in great working condition, using the free version and the step by step guide on updating every driver.

Step By Step Guide

When you open the application, you will see the screen below. Press the big “Scan Now” button to start the driver scanning process of the application. Depending on your computer’s speed and the hardware installed this can take a few seconds or a few minutes.

 

main page

Once the scanning has been completed, you will see the result below. There’s a list with devices that can be updated with new drivers and a list of devices that’s already up to date. We’re interested in the list that needs to be updated.

Click on the Update button to start downloading. If the application asks for a restore point, just tell it that you already did this. Don’t use the Update All feature, that’s only in the paid version.

scan results

This is the screen when downloading the drivers. This might take some time for some of the packages as the download speed is pretty capped.

downloading

When the download is completed, you want to pick the “Manual Installation” mode. Automated installations are again only supported in the Pro version, but adjusting your drivers is easy enough if you stick to this guide.

manual installation

As soon as you press the Continue button, a Windows Explorer will pop up. Click inside the address bar at the top, and copy the entire path using CTRL + C. Once you’ve copied the path, you can close the explorer window.

copy path

The next step is opening the Device Manager in Windows. This can be done really quick by pressing the windows + X button on your keyboard and selecting the “Device Manager from the popup window.

window x

The goal is now to find the correct device. In most cases the name is going to match what you downloaded, but on a fresh system the names might be extremely generic. So if you cannot find the device immediately, there’s a nice trick. Press the grey information button next to the device for which you downloaded the drivers in the Driver Easy app, this opens a small overlay:

info

The overlay shows the new driver info, but when you click on “Device Information”, you will receive the key info for finding your hardware in the Device Manager:

info 2

These Hardware IDs are what uniquely identifies a piece of hardware in your system. There’s not a single device with the same ID in your system, so now that we know what we are looking for, we can start our search in the Device Manager. Open the properties of the hardware you think matches what you want to update:

device manager

Go to the Details tab, and select the Hardware IDs from the dropdown menu.

hardware id

Compare the list to what the Driver Easy application shows you. If they match, then you found the piece for which you have just downloaded the drivers.

device manager match

Now that we compared the data, we know this is our device. So go to the driver tab, and press the “Update Driver…” button to continue the process.

update driver

You want to browse for the files you downloaded, so don’t select the automated update. This will in most cases just tell you that your device is up to date, which it isn’t. So just press “Browse my computer for driver software”.

browse driver

In the next screen you want to replace the path being displayed by the one we copied from the Windows Explorer folder. Because that’s where we stored the drivers. So select all the text inside the input field, delete it and paste inside the path we copied at the beginning.

path driver

Now finalize the process by pressing the Next button.
Repeat this for all the drivers needing an update, and before you know it, your system is running with the latest version.

Just make sure to reboot the system once you’re done with installing ALL drivers. No need to reboot in between installations.

Load-balancer requests in the application

Load-balancers.

Almost every platform uses them these days to distribute the incoming requests between applications, to make sure one node or cluster does not get overloaded and that all users experience an acceptable performance.

The downside of these load-balancers however is that they need to send out some kind of keep-alive messages to the back-end, in order to verify whether the various endpoints they are balancing are still reachable. In our case, this was done by triggering a specific URL and check if we get an HTTP 200 response.

Now without disclosing too much of the internals, we track every web-request, rely on sessions and don’t want to pollute our database with information that’s not relevant to the system. So we originally had the idea to filter out all load-balancer requests from the controllers. Sounds perfectly okay so far, right? Except code wise this was a nightmare. We had a bunch of filters, an API to support and sessions to clean up. This resulted in the ApplicationController becoming a mess of hooks, cleanup code and basically undoing everything Rails did when a new request came in.

When another change-request came in to filter out session data from Redis for the load-balancer, I started asking myself the question: Do we even need to hit the Rails stack in order to know our application is up and running? The answer to that, is no. You don’t need to hit Rails to know whether your application is up and running.

Rails has this feature called Rack Middleware. Creating a custom middleware that responds simply to the load-balancer requests, we created a simple solution that returns an empty HTTP 200 response for the load-balancer, but processes all other requests further up the stack.

  • The Rails stack is never called. This means no cleaning of sessions, data or implementing dozen’s of hooks and if-statements to filter out load-balancer requests.
  • The middleware runs before everything else, so we don’t even need to load all code or triggers
  • The load is removed from the database and Redis system as the calls are never made
  • A lot of the code is reduced to a single module.
module Middleware
  class LoadBalancer
    def initialize(app)
      @app = app
    end

    def call(env)
      params = { url: env['REQUEST_URI'], ip: env['REMOTE_ADDR'] }
      return blank_response if LoadBalancer.skip_web_request?(params)
      @app.call(env)
    end

    def blank_response
      [200, { 'Content-Type' => 'text/html', 'Content-Type' => 0 }, ['']]
    end

    class << self
      def skip_web_request?(url:, ip:)
        skip_web_ips.include?(ip) && skip_web_urls.include?(url)
      end

      def skip_web_ips
        Settings.proxy.trusted_ips
      end

      def skip_web_urls
        ['http://our_fancy_balance_url']
      end
    end
  end
end

So basically what this class does it return an empty HTTP 200 response if the request matches our Load-Balancer request or delegate it up the stack in all other cases.

To get the load-balancer to work before everything else in your stack, you need to create an initializer for Rails and add the following code:

Rails.application.config.middleware.insert(0, ::Middleware::LoadBalancer)

 

Extracting functionality to a Service

Aether,

The name I’ve given to my new service that I am developing at work. The goal is a complete data and logic isolation of one of our features, extracting it from the monolithic web-application we currently have running for our customers.

And while the idea in itself is amazing, the actual implementation is not so easy. The goal is to have a service that crawls the web for data, transforms it and stores it inside our system using the correct configuration and structure. The problems however are:

  • The core is so tightly coupled, that I’m not even sure I can start on this without some preliminary refactoring.
  • There is a data-dependency in both systems, where I do not see an easy separation.
  • There’s a constant need for synchronising data between the systems, which makes me wonder if there’s really a need to extract this.
  • Once we start on this, we need to drive it through completely.

Our Product Owner sees the issues and supports that we need to clean up our technical dept regarding this feature. The business however has requirements that need to be fulfilled as well. Doing both at the same time might be possible I suppose, but do we want that?

  1. We could say that all feature development for this topic is on hold, and the new service needs to be finished first. (We all know how “finished” software is)
  2. We port over the established components and keep developing features in the app, porting them later  (refactor hell)
  3. We put the service on hold and finish the new features first (like that’s ever going to happen)

All three approaches have their benefits and downsides. The biggest problem I have right now is that I see no clean technical solution at the moment on the sync need between the both of them, and how we can proceed with this in an orderly manner.

I’ve tossed the problem in front of the team, and I’m waiting on feedback at the moment, but my mind is wandering, and a little voice says to keep everything in the monolithic application right now and go for code-isolation first, and data-isolation later on.

Lint/ScriptPermissions for Rakefile?

Today I wanted to activate this rule. The cop for this is actually straight forward, you don’t want to add/write script permissions inside your scripts. We have a Rakefile in our application, as any good standard Ruby on Rails application has. And at the top of the file, this is written:  #!/usr/bin/env rake

There is a problem with adding this, namely that your system will use whatever rake is defined, and not necessarily the one you had in mind or configured through your Gemfile or Bundler. That’s why it’s better to NOT include these lines in your script, and make sure the script is actually executable when it needs to be, or you’re using the right commands to do so like bundle exec rake my_script.

Now why doesn’t it make sense to add this as well? The cop kind of gives it away. The error message is that the file doesn’t have any execute permissions, which honestly it should not have in the first place. Rake is running and needs to be executable, but your Rakefile is the script being parsed by Rake. At least that’s how I understand it. I’ve never had to set execute permissions on this file before.

The current Ruby on Rails master branch doesn’t have this entry in it either, perhaps older versions used to have this, but seeing as this is not required anymore, I opted to activate this rule AND remove the line from our Rakefile​.

Binary Gap

So,

Today I was given a coding challenge. Or rather I took one voluntarily to prepare myself for the future.  I know there are companies that require candidates to perform a technical test when applying, and there’s that don’t.

I understand the requirement. A good interview includes a coding test, because you want to see your candidate think and what kind of code he writes to solve a particular problem. I personally don’t care if a candidate did not get the correct solution during the test. You simply cannot know everything, and I’m usually more interested in how someone approaches a problem and comes to a solution.

But back to the test: I was asked to figure out the binary gap for any given number. The binary gap is the largest repeating amount of 0 in the binary notation of that given number. So for example, the binary gap for 15 is 0, because 15 in binary is 1111. For 16 however it’s 4, as 16 in binary is 10000. I hope you understand the question.

# Author: Arne De Herdt
#
# Calculates the binary gap for any given number.
# The binary gap is the largest repeating amount of 0
# in the binary notation of a given number.
#
# For example:
# n = 1041=10000010001_2 => 5
# n = 16 = 10000 => 4
#
def binary_gap(n)
  highest_count = 0
  binary_notation = "%b" % n
  counter = 0

  binary_notation.each_char do |character|
    if character == "1"
      highest_count = counter if counter >= highest_count
      counter = 0
    else
      counter += 1
    end
  end

  return highest_count
end

Is this code covering all cases? Yes, it does. It scored 100% on the Codility website, where I got it from. Is this code I want to be running in a production environment? Most likely not. This code is slow and consumes memory. Classic O(n) space problem where the memory depends on the input.

Can I write production code? Probably. Given a few iterations and improvements I can come up with some magical code in Ruby that does it faster and better.  But is that something I want to show off with on these tests? Rather not. This code is way easier to explain for a thinking process, and gives me a chance to also address the issues with it, showing my understanding of programming patterns and designs.

Feel free to leave comments on how you’d approach this, or if you disagree with me or not.

Precedence of Operations in Ruby

Okay,

Today I fixed a weird bug, that I cannot even fully explain. We rely on CanCanCan to handle authorization of actions in our Ruby on Rails application. When something is not allowed, or the user is simply not logged in, we want to redirect the user back to the root, or to the login page of the application, depending on the situation.

Instead of having to write all of this in every controller, we created a small module to do the work for us, and this is included in the ApplicationController:

def permission_denied(*)
  session[:"#{permission_denied_resource}_permission_denied"] = true
  session[:"#{permission_denied_resource}_return_to"] = request.url
  response.headers['X-Permission-Denied'] = true if Rails.env.test?

  flash[:alert] = I18n.t('devise.failure.access_denied') if current_user

  respond_with do |f|
    f.html do
      redirect_to permission_denied_path and return unless request.xhr?
      render json: flash, status: :unauthorized
    end
    f.js do
      flash.discard
      render json: flash, status: :unauthorized
    end
    f.json do
      flash.discard
      render json: flash, status: :unauthorized
    end
  end
end

Now in certain cases, especially with links opened from Office documents, this would result in a double render error. The line causing the problem being this one:

redirect_to permission_denied_path and return unless request.xhr?

According to the precedence of Ruby this does not make much sense. an unless-modifier has a lower precedence than the and operation. My understanding is that the redirect_to and return should be executed together and then the unless statement is verified to actually do it. Or that is what is intended. But that didn’t match with the error that was happening.

When I wrote the code as follows, this problem disappeared:

f.html do
  if request.xhr?
    render json: flash, status: :unauthorized
  else
    redirect_to(permission_denied_path) and return
  end
end

The behaviour is exactly the same as we wanted to achieve with the unless modifier. However this does not raise and double rendering errors when clicking a link from a Word document.

Lesson Learned:  When combining multiple statements, it’s often better to write them out the long way and not cram it all together into a single line.

Railsconf 2017

Been too long since I wrote an article about coding related stuff, so might as well write about the the trip to Phoenix, Arizona and attending the Railsconf 2017!

For me it was the first time that I actually attended the Railsconf. I’ve always been going to Euruko instead, which is hosted in a different country each year across Europe. Adding to my first attendance for Railsconf, it was also the very first time that I visited the US. Honestly, this has changed my view on the US completely, in a positive way, as I had a very pleasant experience in Phoenix.

Down to the points!

Form Objects

I’m not really a fan of them. Mostly because of the way they have been (ab)used in our application really. I understand the point behind them, and I can even identify cases in our application where using a form object makes sense. Especially when the page is displaying a compound of 3 to 4 entities into a single one. A Form object really shines at places like this.

At the Railsconf, there was a talk about Form objects using Reform. I do not like Reform. I have a big problem with Reform on how they even implement certain things, and their DSL is honestly a complete mess. Combine this with the issues they have every upgrade as well as their clear approach from stepping away from Rails, I spend more time making Reform work inside our Rails application then actually adding useful functionality.

For me a Form Object should be written simple. Do it on your own, but be on your own. You can include the various methods for ActiveRecord and ActiveSupport so that you have validations and can mimic the behaviour of a basic model.

Strong Parameters

Many people, including a large part of the team I work in seems to have a major issue with Strong Parameters in Rails. And honestly I don’t understand why. I find the usage of these parameters rather straightforward and simple, as long as you keep your forms straightforward and simple.

Things get complicated when you are using dynamic parameters or deeply nested structures on your forms. But really, are you going the right way then with such structures?

Rails 5.1

Yup, it’s released. Announced by Aaron Patterson during the final keynote. (Which was simply hilarious to follow). I’m still in the process of upgrading our application to 5.0, which honestly is a journey in itself:

  • Implementing the new standards
  • Getting rid of all deprecation warnings
  • Dealing with the breaking changes
  • Dealing with the undocumented changes (I’m looking at your hash operations)
  • Making sure it all works

I think I’m almost done with it now, and then can progress to the next version, but seriously, updating a massive application that runs in production to the next Rails version is always a big thing.

Convention over Configuration

I’m really happy this got hammered once more at the conference. Many people seem to forget that the goal of Ruby on Rails is “programmer happiness”. We don’t need boilerplate code, or dozens of rules and regulations to program something out.

We want a convention, a guideline on how it works and people sticking to it. A happy programmer is a productive programmer.

 

Well, that’s all for now.
Just wanted to write this out, and hopefully soon I can write a dedicated article about upgrading from Rails 4 to Rails 5, and all the quirks you need to keep in mind while jumping through the different hoops.

Carbine’s WindowManager

Okay,

After talking with CRB_Moenzuel, I’m starting to understand how the client’s window manager works, and how Addons can use it for their own purpose to track the windows of the Addon.

There’s a few steps that someone needs to implement in order to properly use the WindowManager, but one you understand the basics, it becomes a pretty powerful tool.

WindowManagementReady Event

This is the key event that an Addon needs to be listening for. It gets raised by the client once the WindowManager is ready to take requests for handling your windows. Most Addons, including those by Carbine register for this event in their OnDocumentReady call.

 

function MyAddon:OnDocumentReady()
  Apollo.RegisterEventHandler("WindowManagementReady", "OnWindowManagementReady", self)
end

function MyAddon:OnWindowManagementReady()
  Event_FireGenericEvent("WindowManagementRegister", {strName = "MyAddon", nSaveVersion = 1})
  Event_FireGenericEvent("WindowManagementAdd", { wnd = self.wndMain, strName = "MyAddon", nSaveVersion = 1})
end

The above example register our function to handle the asynchronous callback of the WindowManager and uses the opportunity to :

  1. Register our Addon in the WindowManager
  2. Register our Addon’s main window as the window to track.

The ideal situation as explained by CRB_Moenzuel:

Ideally Register happens in MyAddon:OnWindowManagementReady and Add happens when the window is created right before being shown. You also want to call MyAddon:OnWindowManagementReady after registering for the event to cover the case you are loading after the window management addon has loaded

Taking the above into account, your code will most likely look more like this:

-- Start loading the XML and continue when it's done.
function MyAddon:OnLoad()
   self.xmlDoc = XmlDoc.CreateFromFile("MyAddon.xml")
   self.xmlDoc:RegisterCallback("OnDocumentReady", self)
end

-- XML is loaded, start building our window and event handlers
function MyAddon:OnDocumentReady()
  if self.xmlDoc == nil then
    return
  end

  Apollo.RegisterEventHandler("WindowManagementUpdate", "OnWindowManagementUpdate", self)

  -- Do all stuff you need, including making your windows
  self.wndMain = Apollo.LoadForm(self.xmlDoc, "MainForm", "Window", self)

  Apollo.RegisterEventHandler("WindowManagementReady", "OnWindowManagementReady", self)
  self:OnWindowManagementReady() -- to beat the racing condition
end

-- This either gets called by the Windowmanager when the event is raised
-- or our Addon does it itself.
-- Either way, the window manager will handle duplicates.
function MyAddon:OnWindowManagementReady()
  Event_FireGenericEvent("WindowManagementRegister", {wnd = self.wndMain, strName = "MyAddon" })
  Event_FireGenericEvent("WindowManagementAdd", {wnd = self.wndMain, strName = "MyAddon"})
end

WindowManagementUpdate Event

This is a key event that get’s raised by the EventManager every time one of the following actions happens:

  • The tracked window is being moved by the User.
  • The user clicks the reset button of inside the Positioning window of the Interface Options

As with the WindowManagementReady event, the callback needs to be registered in the OnDocumentReady function of your Addon.

function MyAddon:OnDocumentReady()
  Apollo.RegisterEventHandler("WindowManagementUpdate", "OnWindowManagementUpdate", self)
end

function MyAddon:OnWindowManagementUpdate(tSettings)
  // do stuff
end

The callback of the event comes with a parameter called tSettings. This parameter is a table with the following properties:

  • tSettings.wnd : The window that has been moved or reset.
  • tSettings.bHasMoved : A boolean indicating whether the window was moved.
  • tSettings.strName : The name of the Window that has been moved or reset.
  • tSettings.bDefaultMoveable : A boolean indicating whether the window was moveable by default. (DEPRECATED?)
  • tSettings.bMoveable : A boolean indicating whether the window is moveable.
  • tSettings.bDefaultRequireMetaKeyToMove : A boolean indicating whether the window requires CTRL to move (DEPRECATED?)
  • tSettings.bRequireMetaKeyToMove : A boolean indicating whether the windows requires CTRL to move.
  • tSettings.tCurrentLoc : table containing the current location of the Window.
  • tSettings.nPosX : The x-coordinate of the Window
  • tSettings.nPosY : The y-coordinate of the Window

While you’re normally not required to do anything specific, you can use the available information to make your Addon respond to certain conditions.

WindowManagementRemove Event

This event needs to be raised by your Addon if you wish to remove it from the WindowManager. The event takes a single table containing the name of the window to be removed.

Event_FireGenericEvent("WindowManagementRemove", {strName = "MyAddon"})

Important:  You should call this when creating and adding a Window and later on destroying the window. Otherwise the manager keeps a reference to a window that no longer exists.

Refactoring Code: Dynamic functions

Okay,

We have a factory that is responsible for creating certain class instances to run background jobs. This class was originally 650 lines long, doing nothing more then for every background entity defining the function my_background_class_command.

for……every……single….class inside our CommandEntity namespace….

Refactoring

Rails has this dogma called Convention over Configuration. I wanted to implement something similar because this factory was nothing more than creating a method for every entity we support.

  • Convention over Configuration
  • Filenames need to match the class they define
  • The entities all reside in their own namespace/folder

Using those three rules, I created a single class method for our factory that checks the entire folder structure, determines whether the class is a correct type and defines the required methods on our factory:

module CommandEntity
  class Factory
    include Singleton

    # Constants
    PATH = 'path/to_my/command_entity/'
    DIRECTORY = Rails.root.join(PATH)
    EXCLUDED = [
      DIRECTORY.join('my_module.rb'),
      DIRECTORY.join('my_second_module.rb'),
      DIRECTORY.join('some_error_class.rb'),
      DIRECTORY.join('factory.rb'),
      DIRECTORY.join('magical_helper.rb'),
      DIRECTORY.join('magical_second_helper.rb'),
      DIRECTORY.join('database_magic.rb'),
      DIRECTORY.join('serializers/json.rb')
    ].freeze

    class << self
      def command_factory
        Dir[DIRECTORY.join('**/*.rb')].entries.each do |file_name|
          next if EXCLUDED.include?(Pathname.new(file_name))

          chunks = file_name.gsub(Rails.root.to_s, '').gsub('.rb', '').gsub(PATH, '')[1..-1]
          method_name = chunks.gsub(::File::SEPARATOR, '_')
          structure = chunks.split(::File::SEPARATOR).reject(&:blank?)

          define_method("#{method_name}_command") do |options = {}|
            "::CommandEntity::#{structure.map(&:camelcase).join('::')}".constantize.new(options)
          end
        end
      end
    end

    command_factory
  end
end

So what exactly are we doing here right now:

  1. We loop over every entry inside the folder that holds our entities
  2. If it’s something to ignore, we move on to the next entity
  3. The filename has everything we need, so throw out the useless parts
  4. Build the method name
  5. Tell the method to dynamically create the class and instantiate it

The result: Reduced a class that was 650 lines long to a mere 50 while retaining all functionality.

The kicker: We don’t even need the class cause all we do is some_class.new(options) for which we really don’t even need a factory in the first place…..

Create a free website or blog at WordPress.com.

Up ↑