Project Euler Problems

First time I came across a project-euler problem was at Stack Overflow. While answering an algorithm question, I found the Project Euler provides a fun way to learn new concepts and keep my problem solving and mathematics skills sharp.

Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.

So I decide to solve one problem a day and keep my solutions here. To spice things up, I want to solve each problem with two different languages. One imperative language that I am already comfortable with, such as C#, ruby, java, javascript. Another one, I would use a functional language.

Problem 1: Multiples of 3 and 5

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.

Solution 1

C#

It could be something like this

var result = 0;

for(var i =1; i < 1000; i ++) {
  if (i % 3 == 0 || 1 % 5 ==0 ) {
    result += i;
  }
}

But NO, I really don’t want to see any for-loop or while-loop here. Using C# doesn’t mean you cannot do it in a concise, declarative style. Here you go:

Enumerable
.Range(1, 999)
.Where(n => (n % 3) * (n % 5) ==0)
.Sum();

Solution 2

Lets do it in a real functional language.

F#

[1..999] |> List.filter (fun n -> (n % 5) * (n % 3) = 0 ) |> List.sum

Build a Backend With Node.js, Container and Azure (2)

Node.js is a popular a server-side framework for building high performance backend. In this post we will be looking at creating a backend API using Node, Express and Mongoose. It will handle user registration requests and publish a message to job queue.

Creating the App

Our project structure is like the following. We will keep this very simple for the demonstration purposes.

├── server.js
└── src
    ├── api.js
    └── email_service.js
├── config
│   └── config.js
├── model
│   └── user.js
├── package.json
├── docker-compose.yml
├── Dockerfile

Fist, create the package.json

npm init

This will ask you a bunch of questions, and then write a package.json for you. Now install the packages we will be using in this project.

npm install --save express mongoose body-parser amqplib

Then, we define a user model with Mongoose. Mongoose provides a schema-based way to model application data. It includes built-in type casting, validation, query building, business logic hooks and more, out of the box.

var mongoose = require(‘mongoose’);

var userSchema = new mongoose.Schema({
  email : { 
    type: String, 
    trim: true, 
    required: true, 
    index: { unique: true, uniqueCaseInsensitive: true },
    validate: {
      validator: function(v) {
            p =/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/i
            p.test(v);
        },
          message: '{VALUE} is not a valid email address!'
        }
    },
    created_at: { type: Date, default: Date.now },
  }
)

module.exports = mongoose.model('User', userSchema);

Now lets look at the api.js. In this file we define how our api responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on).
Here we has a handler function that accepts a post request, creates a new user. Once the registration has completed, it publish an email sending the job to the message queue.

app.js

app.post('/register', function(req, res) {
    var user = new User(req.body);
    user
    .save()
    .then(
        function(u) {
            email_service.send_welcome_email(u);
            return res.json({success: true})
        },
        function(err) {
            return res.status(400).json({sucess: false, data: req.body, error: err})
        }
    )
});

We will delegate the work of sending email task to the email_servie. Note the send_welcome_email is a non-block function.

email_service.js

EmailService.prototype.send_welcome_email = function(customer) {
    var self = this;

    if (self.ch) {
         process.nextTick(function() {
                 send_to_queue(self.ch, email_queue, customer.email);
         })
    } else {
        self.conn.createConfirmChannel( function(err, ch) {
            if (err) {
                return console.error(err);
            }
        self.ch = ch;
        ch.on("error", function(err) { console.error(err)});
        send_to_queue(self.ch, email_queue, customer.email)
      })
    }                                        
}

function send_to_queue(ch, q_name, content) {
    ch.publish('', q_name, new Buffer(content), { persistent: true },
        function (err, ok) {
            if (err) {
                console.error("[AMQP] publish ", err);
                pubChannel.connection.close();
            }
    })
}    

The email service publishes an email task to the message queue. In next post, we will implement a work process that picks up an email task from the message queue and sends an email out through SMTP.

Troubleshoot Your node.js App Deployment on Azure Website

Deploying Node applications to Azure website seems simple. Just set up continuous deployment on the Azure Portal. Azure will build, test and automatically deploy your app when you check in code. Everything runs so well until you open a browser, navigate to the website url and see this: 500 internal server error. That was exactly the case we had in the last project. The application was written in node & express with dependancies to 52 npm packages including babel, redis, new relic, gulp, webpack. It works like a charm on local servers, just not on Azure website with git deployment. As usual, most documentation we found online are about “Hello world” which won’t help much with a production problem. Here are some of the steps we used to diagnose and analysis the deploy problem and make it work.

Test compilation on windows

During npm install, some node modules with native extensions will be compiled to match the hosting OS and architecture(x86 or x64). If the application is developed on Mac OS, Linux and deploy to Azure website, first thing to do is to confirm that every module is compatible with Windows platform.

##web.config file
Under the hood, Azure website hosts node.js apps with iisnode. You need a web.config to config iisnode. If you use git deployment, when Azure detects an app.js or server.js file, it will automatically generate a web.config. Or you can add a custom one manually. Open the web.config file, and check the handlers section. Make sure it points to the correct application entry point.

<handlers>
    <add name="iisnode" path="app.js" verb="*" modules="iisnode"/>
</handlers>

Environment variables

You can set environment variables through a website portal or Azure CLI. The easiest way to check their value is through website portal, under config section, choose app settings. Or if you are using Azure CLI, run

azure site config list your-site

Make sure there is no PORT setting. iisnode will use this variable to pipe IIS to your app.
Also check value of WEBSITE_NODE_DEFAULT_VERSION, it sets default node version used by the target website.

Check in node_modules

When using git deployment, normally we don’t check in node_modules. However, according to this Azure documentation

Azure Websites does not support all native modules and might fail at compiling those with very specific prerequisites.

So if all the about steps don’t help, you might want to test it out by checking in you node_modules. Remember, before checkin, run npm install on a Windows platform with some architecture of you website.

Enable Application log

Add the following to your iisnode.yml

node_env: production
loggingEnabled: true
devErrorsEnabled: true

Then you can use Azure CLI to live stream the logs

$ azure site log tail sampleBlog

Debug with Kudu

Kudu is the engine behind git deployments in Azure Web Sites.
Every Azure web site has an associated ‘scm’ service site at https://your-site.scm.azurewebsites.net/. It provides a set of tools for troubleshooting and analysis your node.js website. You can:

Open the debug console, choose CMD or powershell.
Then start you app with node.exe directly

$ cd D:\home\site\wwwroot> 
$ node app.js

If you see an error from a node module, it might be caused by either wrong node version or corrupt node_module. Check the current node version

$ node -v

Make sure it is your target version. Run npm install for the failed module if necessary. Once the app starts from console, you can close it and restart your website. Open a browser and see your website start working.