NodeJS → Go
Alan Braithwaite
@Caust1c
github.com/abraithwaite
Segment Inc
Why?
Performance
Security
Reliability
Flexibility
Productivity
Why?

The architecture

Verification of New API

Verification of New API

Release Proceedure
Roll out new API Forwarder pointing to new API
Scale up new API as more traffic is moved over
???
🤑🤑🤑
Incident Free Hermit
Challenges Encountered
Timestamps

Challenges Encountered
var formats = []string{
// 99% case. RFC3339 handles deserializing ISO8601 as well.
time.RFC3339,
// everything else (we've seen so far) that JS accepts
time.RFC1123Z,
time.RFC822Z,
"2006-01-02T15:04:05-0700",
// (seemingly rare) JS case.
"2006-01-02 15:04:05 -0700",
// --- Keep formats with tz offset above this line ---
time.RFC1123,
time.RFC822,
"2006-01-02T15:04:05.00",
"2006-01-02T15:04:05",
"2006-01-02T15:04:05.000",
"Jan _2, 2006 3:04:05 PM",
// counterpart to above
"2006-01-02 15:04:05",
}
Timestamps
Challenges Encountered
Timestamps
x = new Date("01 Jan 18 00:01 PST")
Mon Jan 01 2018 00:01:00 GMT-0700 (Pacific Standard Time)
const int8_t DateParser::KeywordTable::
array[][DateParser::KeywordTable::kEntrySize] = {
// some omitted for brevity...
{'u', 't', '\0', DateParser::TIME_ZONE_NAME, 0},
{'u', 't', 'c', DateParser::TIME_ZONE_NAME, 0},
{'z', '\0', '\0', DateParser::TIME_ZONE_NAME, 0},
{'g', 'm', 't', DateParser::TIME_ZONE_NAME, 0},
{'c', 'd', 't', DateParser::TIME_ZONE_NAME, -5},
{'c', 's', 't', DateParser::TIME_ZONE_NAME, -6},
{'e', 'd', 't', DateParser::TIME_ZONE_NAME, -4},
{'e', 's', 't', DateParser::TIME_ZONE_NAME, -5},
{'m', 'd', 't', DateParser::TIME_ZONE_NAME, -6},
{'m', 's', 't', DateParser::TIME_ZONE_NAME, -7},
{'p', 'd', 't', DateParser::TIME_ZONE_NAME, -7},
{'p', 's', 't', DateParser::TIME_ZONE_NAME, -8},
// ...
}
Other Challenges Encountered
- Javascript is loosely typed
- Falsey
- Null
- Undefined
- Unknown fields must be preserved
-
github.com/tidwall/gjson
-

New Release Proceedure
- Release tiered by customer plan level
- Manual redshift query
- Embedded CSV into API Forwarder to query
- Released over 4 months
SEVs Related to Rewrite
incident-free-hermit (corrupted timestamps for all customers across 8 hours)
incident-needed-emu (imbalanced autoscaling rules between api-forwarder and api)
sev-broad-moose (canary configs in treb caused reset in desired count for service, causing delays)
sev-slow-cockroach (projectId:null handled improperly caused dropped data for 8h on one source)
sev-blop-shibe (marketo integration bad signatures caused <5min dropped marketo data)
sev-lively-mouse (secret in event body for authentication, affected 1 or two customers)
sev-low-hedgehog (performance for overflow. probably would have knocked old API over)
sev-drab-quokka (pentester added library integration, bad behavior from old API)
sev-clumsy-possum (validation errors caused dropping of page/screen calls)
Summary
Rewrites are challenging
Avoid them if possible
Setup a rock solid validation system against real customer data
Go made it easier ;-)
Thank you
Alan Braithwiate
Segment
@Caust1c
https://github.com/abraithwaite
https://segment.com

Rewrite from NodeJS to Go
By Alan Braithwaite
Rewrite from NodeJS to Go
- 37