Random Musings on Technology

The Path to Kueski 2.0

 • 

Back in the day (5 years ago) I wrote a good blog post related to a migration the Engineering team did from a monolithic infrastructure into a "microservice based" architecture.

The original URL is this, but I've seen it has gone down a couple of times in the last days so I saved a copy of it in archive.is:

The Path to Kueski 2.0 (Archive).

Another good blog post that is worth saving, is the Better Logging (Archive) post by Jorge del Rio which has good ideas about logging in production environments.

Web Sequence Digrams

 • 

A nice script to generate sequence diagrams in an HTML page:

Taken from: https://unpkg.com/js-sequence-diagrams-autorenderer@1.0.1/index.js

// JS-sequence-diagrams auto-renderer; renders a document using JS-sequence-diagrams (https://bramp.github.io/js-sequence-diagrams/)
// See readme.md for usage instructions
// Pretty inefficient, but it works:
const a = document.createElement('script'); a.setAttribute('src', 'https://cdnjs.cloudflare.com/ajax/libs/webfont/1.6.28/webfontloader.js');  
document.head.appendChild(a);  
a.onload = () => {  
  const b = document.createElement('script'); b.setAttribute('src', 'https://cdnjs.cloudflare.com/ajax/libs/raphael/2.3.0/raphael.min.js');
  document.head.appendChild(b);
  b.onload = () => {
    const c = document.createElement('script'); c.setAttribute('src', 'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js');
    document.head.appendChild(c);
    c.onload = () => {
      const d = document.createElement('script'); d.setAttribute('src', 'https://cdnjs.cloudflare.com/ajax/libs/js-sequence-diagrams/1.0.6/sequence-diagram-min.js');
      document.head.appendChild(d);
      d.onload = () => {
        const diagram = Diagram.parse(document.body.textContent);
        document.body.textContent = "";
        const x = document.createElement('div');
        document.body.appendChild(x);
        diagram.drawSVG(x, {theme: 'simple'});
      }
    }
  }
}

As an example usage, paste this into a file test.html and open it in your browser:

Jon->Ygritte: Do you remember the cave?  
Note right of Ygritte: Long silence...  
Ygritte-->Jon: We should have stayed in that cave  
Jon->Ygritte: We'll go back there.  
Ygritte-->Jon: You know nothing Jon Snow


# Rendered using JS-sequence-diagrams (https://bramp.github.io/js-sequence-diagrams/) by the line below:
# <script src="https://unpkg.com/js-sequence-diagrams-autorenderer@1.0.1/index.js"></script>

CodeWars Kata: Decode the Morse code, advanced

 • 

I like solving programming exercises sometimes when I have free time. It is fun and it helps keeps the "programming problem solving brain", particularly as day to day management work gets further away from programming.

This time I solved a nice Kata called "Decode Morse, advanced" from the great site called CodeWars. I wanted to put it here to preserve the solution for posterity.

Usually, these type of exercises have a "gotcha" element. The one-thing that you have to solve in order to implement it. In this case is finding the rate of the message. After a couple of approaches, the one in the code is the one I liked the most.

This is my final code:

var decodeBits = function(bits){

    // remove trailing 0s from the beginning and the end

    bits = bits.replace(/^0+/,'').replace(/0+$/,'')

    // find the rate by getting the "minimum" cluster of 1s or 0s, corresponding to a 'dot'    
    let rate1s =  bits.split('0').map(c => c.length).filter(c=> c!=0).sort((a,b)=>{return a - b})[0]
    let rate0s =  bits.split('1').map(c => c.length).filter(c=> c!=0).sort((a,b)=>{return a - b})[0] ||  rate1s
    let rate = Math.min(rate1s , rate0s);
    // replace pauses between words
    let reg = new RegExp("0".repeat(rate*7),"g");
    let data = bits.replace(reg," ");

    // replace pauses between characters
    reg = new RegExp("0".repeat(rate*3),"g");
    data = data.replace(reg,'|')    
    let words = data.split(" ")
    let output = []
    words.forEach(word => {
     let wordOutput = []
     word.split('|').forEach(letter => {
       // get dashes
       let reg = new RegExp("1".repeat(rate*3),"g");  
       letter = letter.replace(reg,'-');
       // get dots
       reg = new RegExp("1".repeat(rate*1),"g");
       letter = letter.replace(reg,'.')

       // remove 0s
       letter = letter.replace(/0/g,'')
       wordOutput.push(letter)
     });
     output.push(wordOutput);         

    })
    return output;
}

var decodeMorse = function(morseCode){  
  return morseCode.map(word => {
    return word.map(letter => MORSE_CODE[letter]).join('')
  }).join(' ');
}

Some tests:

Test.describe("Example from description", function(){  
Test.assertEquals(decodeMorse(decodeBits('1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011')), 'HEY JUDE')  
Test.assertEquals(decodeMorse(decodeBits('11111111111111100000000000000011111000001111100000111110000011111000000000000000111110000000000000000000000000000000000011111111111111100000111111111111111000001111100000111111111111111000000000000000111110000011111000001111111111111110000000000000001111100000111110000000000000001111111111111110000011111000001111111111111110000011111000000000000000111111111111111000001111100000111111111111111000000000000000000000000000000000001111111111111110000011111000001111100000111110000000000000001111100000111111111111111000001111100000000000000011111111111111100000111111111111111000001111111111111110000000000000001111100000111111111111111000001111111111111110000000000000001111111111111110000011111000000000000000000000000000000000001111100000111110000011111111111111100000111110000000000000001111111111111110000011111111111111100000111111111111111000000000000000111111111111111000001111100000111110000011111111111111100000000000000000000000000000000000111110000011111111111111100000111111111111111000001111111111111110000000000000001111100000111110000011111111111111100000000000000011111111111111100000111111111111111000000000000000111110000011111111111111100000111111111111111000001111100000000000000011111000001111100000111110000000000000000000000000000000000011111111111111100000111111111111111000001111111111111110000000000000001111100000111110000011111000001111111111111110000000000000001111100000000000000011111000001111111111111110000011111000000000000000000000000000000000001111111111111110000000000000001111100000111110000011111000001111100000000000000011111000000000000000000000000000000000001111100000111111111111111000001111100000111110000000000000001111100000111111111111111000000000000000111111111111111000001111111111111110000011111000001111100000000000000011111111111111100000111110000011111111111111100000111111111111111000000000000000000000000000000000001111111111111110000011111000001111100000000000000011111111111111100000111111111111111000001111111111111110000000000000001111111111111110000011111111111111100000111110000000000000001111100000111111111111111000001111100000111111111111111000001111100000111111111111111')), 'THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.')  
})

How would you solve it?

AWS EC2-Other usage mystery...

 • 

While managing my company's AWS EC2 usage account, I found out an "unexplained" spike in daily cost on the Billing Explorer. It was a jump from $12 to $39 USD.

Going into the "Cost Explorer" or general AWS billing info only showed a bump in the "EC2-Other" category. However it was a bit difficult to find the right way to "drill down" into what other EC2 usage was causing the cost increase.

EC2-Other Image.

As seen in the image, to get the detail of what the "EC2-Other" comprises in the AWS Cost Explorer interface, you have to select the EC2-Other service in the filter category and then select the "Usage Type" option in the Group-by setting.

In my case, the increased cost was due to one single 1TB disk which I had changed from gp2 into provisioned io, and increased the IO from 3000 to 16000.

If you think about this, AWS is a dangerous place that can byte you back in the wallet if you are not careful or you don't know what you are doing.

I've heard other horror stories of people spending thousands of dollars because of the lack of some planning (like, sudden spike in Lambdas processing!).

Cautionary tale...