Observability in micro-service architectures
Recently, we were fortunate to bring together top CTO talent from inside and outside the First Round Community to share best practices, challenges and insights. Key topics included how to create a great management team, introducing structure to your org, and tools for better technical productivity. Notes from this session are below.
- It's easy to build a management structure when things are early and small. But don't over-optimize this structure. It will change as you bring people on. For example, don't give out management titles until you have at least four teams.
- The best tactic is to have everyone start out as an engineer, then hire an engineering director and split the team in half. This is the cell-splitting model -- grow a team then split it into different cells.
- Don't promote people into management roles too early. It's better to hire a manager than to promote from within the ranks. The latter only causes conflict.
- Always remember, while someone might be a bril
aaron,erin,ron,ronnie | |
abel,ab,abe,eb,ebbie | |
abiel,ab | |
abigail,abby,gail,gail,nabby | |
abner,ab | |
abraham,ab,abe | |
abram,ab | |
adaline,ada,addy,delia,dell,lena | |
adelaide,addy,adele,dell,della,heidi | |
adeline,ada,addy,delia,dell,lena |
package main | |
import ( | |
"github.com/apex/go-apex" | |
"github.com/apex/go-apex/kinesis" | |
"github.com/aws/aws-sdk-go/aws" | |
"github.com/aws/aws-sdk-go/aws/session" | |
"github.com/aws/aws-sdk-go/service/firehose" | |
) |
console.log('Loading function'); | |
exports.handler = function(event, context) { | |
//console.log('Received event:', JSON.stringify(event, null, 2)); | |
event.Records.forEach(function(record) { | |
// Kinesis data is base64 encoded so decode here | |
var payload = new Buffer(record.kinesis.data, 'base64').toString('ascii'); | |
console.log('Decoded payload:', payload); | |
}); | |
context.succeed("Successfully processed " + event.Records.length + " records."); |
{ | |
"id": "custom_id", // the webhook_id passed in the lookup params | |
"status": 200, | |
"type": "company", | |
"body": { | |
// Company attributes | |
} | |
} |
A running example of the code from:
- http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang
- http://nesv.github.io/golang/2014/02/25/worker-queues-in-go.html
This gist creates a working example from blog post, and a alternate example using simple worker pool.
TLDR: if you want simple and controlled concurrency use a worker pool.
In researching topics for RailsCasts I often read code in Rails and other gems. This is a great exercise to do. Not only will you pick up some coding tips, but it can help you better understand what makes code readable.
A common practice to organize code in gems is to divide it into modules. When this is done extensively I find it becomes very difficult to read. Before I explain further, a quick detour on instance_eval
.
You can find instance_eval
used in many DSLs: from routes to state machines. Here's an example from Thinking Sphinx.
class Article < ActiveRecord::Base
{ | |
"id": "d5639304-f15a-48b5-9711-7bd42e6c4d72", | |
"name": "HotelTonight", | |
"legalName": "HotelTonight, Inc", | |
"domain": "hoteltonight.com", | |
"url": "http://hoteltonight.com", | |
"site": { | |
"url": "http://hoteltonight.com", | |
"title": "HotelTonight | Last-Minute Deals on Great Hotels", | |
"h1": "PLAN LESS. ", |
require 'sinatra/base' | |
class FakeGitHub < Sinatra::Base | |
cattr_reader :emulate_failure | |
def self.reset! | |
@@emulate_failure = false | |
end | |
def self.emulate_failure! |