SlideShare una empresa de Scribd logo
1 de 70
How it’s made: MyGet
Maarten Balliauw
@maartenballiauw
Who am I?
Maarten Balliauw
Daytime: Technical Evangelist, JetBrains
Co-founder of MyGet
Author – Pro NuGet http://amzn.to/pronuget
AZUG
Focus on web
ASP.NET MVC, Windows Azure, SignalR, ...
MVP Windows Azure & ASPInsider
http://blog.maartenballiauw.be
@maartenballiauw
Who am I?
Maarten Balliauw
Daytime: Technical Evangelist, JetBrains
Co-founder of MyGet
Author – Pro NuGet http://amzn.to/pronuget
AZUG
Focus on web
ASP.NET MVC, Windows Azure, SignalR, ...
MVP Windows Azure & ASPInsider
http://blog.maartenballiauw.be
@maartenballiauw
Who am I?
Maarten Balliauw
Daytime: Technical Evangelist, JetBrains
Co-founder of MyGet
Author – Pro NuGet http://amzn.to/pronuget
AZUG
Focus on web
ASP.NET MVC, Windows Azure, SignalR, ...
MVP Windows Azure & ASPInsider
http://blog.maartenballiauw.be
@maartenballiauw
Agenda
NuGet? MyGet?
How we started
What we did not know
Our first architecture
Our second architecture
Multi-tenancy
ACS
Tough times (learning moments)
When business meets technology
Conclusion
NuGet? MyGet?
NuGet? MyGet?
NuGet? MyGet?
Why MyGet?
Safely store your IP with us
Creating packages is hard. We have Build Services!
Granular security
Activity streams
Symbol server
Analytics
I’m not alone!
Xavier Decoster
@xavierdecoster
Yves Goeleven
@yvesgoeleven
Also known as @MyGetTeam
How we started
The real begin? May 09, 2011
NuPack!
Using OData as their feeds
Which is some sort of WCF…
Multiple feeds?
Exchanged some ideas with Xavier
Prototyped something during TechDays Belgium, 2011
Prototype online! May 31, 2011
Technologies used?
Windows Azure
Windows Azure Table Storage & Blob Storage
Windows Azure ACS (no way I’m typing another user registration)
ASP.NET MVC 2
MEF
Here’s some code from back then…
[Authorize]
public class FeedController : Controller {
public ActionResult List() {
var privateFeedTable = PrivateFeedTable.Create();
var privateFeeds = privateFeedTable.GetAll(
f => f.PartitionKey == User.Identity.Name.ToBase64());
var model = new PrivateFeedListViewModel();
foreach (var privateFeed in privateFeeds.Where(f => f.IsVisible)) {
var privateFeedViewModel = new PrivateFeedViewModel();
model.Items.Add(AutoMapper.Mapper.Map(privateFeed, privateFeedViewModel));
}
return View(model);
How about this one?
try
{
privateFeedNuGetPackageTable.Add(privateFeedPackage);
}
catch
{
// Omnomnom!
}
Best practices used back then?
Architecture at the time?
Cloud Services: one web role doing all work
Storage: one storage account
Windows Azure Access Control Service
What we did not
know…
Users would come!
Grew from 5 feeds to 70 feeds in a few weeks
10 feeds per week added thereafter
Data would come!
One user pushed 1.300 packages worth 1 GB of storage
Others started pushing CI packages
Others seemed to be copying www.nuget.org
ReSharper time!
ReSharper time!
A lot of refactoring done
Direct data access -> repositories
Repositories used by services
Services used by controllers
Using best practices
SOLID and DRY (well, not everywhere but refactoring takes time)
Running on two instances (availability, yay!)
We became a startup
Someone mentioned they would pay for our service
Think about business model
Volume of feeds and packages kept going up
Users in EU and US
Our first architecture
Our first architecture - code
Awesome!
Best practices!
Layers!
Typical business application architecture!
Not so awesome…
Best practices!
Are they?
Layers!
No spaghetti code but lasagna code
Typical business application architecture!
Proved to be very inflexible
Our first architecture - infrastructure
Awesome!
Datacenters nearby our users
Centralizes storage
Packages on CDN for faster throughput
DNS fail-over if one of the DC’s went down
No so awesome…
Datacenters nearby our users
Or not?
Centralizes storage
Speed of light! USA was slow!
Packages on CDN for faster throughput
Sync issues, downtime, …
DNS fail-over if one of the DC’s went down
Seems not every ISP follows DNS standards
We persisted!
Local caching in USA added
2 instances in EU, 3 in the USA
Speed of light! Syncing all data kept being slow
Populating cache was a nightmare
CDN kept having issues
Of 3 instances, only 1 was being used with enough load (60%)
We were growing!
We had public subscription plans
We added enterprise tenants (multi-tenancy added)
Resulting in…
Architecture became complex
Caching and syncing became complex
ReSharper time!
Our second
architecture
We had a look at our workloads
Managing feeds and packages
Doesn’t matter much where (sync vs. bandwidth)
Downloading packages
May matter where, let the tenant decide
Builds
Who cares where!
Our 2nd architecture - infrastructure
Our 2nd architecture - code
Our first architecture…
… was scaled across the globe
… but as synchronous as it could be
… prone to all issues with latency vs. synchrony
Event Driven Architecture?*
*disclaimer: we borrowed some concepts from EDA
EDA in MyGet
Some actions put an ICommand on a queue
(ground rule: if it can’t be done in 1 write, use ICommand)
All actions complete with an IEvent on a queue
Handlers can subscribe to ICommand and IEvent
Handlers are idempotent and not depending on
others
Example: log in
2 operations: 1 read, 1 write
Read the profile
Store the profile with LastLogin date
No use of ICommand
Finishes with UserLoggedInEvent
Example: change feed owner
Many operations!
Read two user profiles
Read current access rights
Change access rights
Push new privileges to SymbolSource.org
One command, one event
ChangeFeedOwnerCommand
FeedOwnerChangedEvent
Example: change feed owner
Gain?
We now run on 2 instances, mostly for redundancy
Average CPU usage? 20% (across machines)
Flexibility!
Way easier to implement new features!
New feature: activity log
Simply subscribe to events we want to see in that log
Storage
No relational database (why not?)
Event-driven architecture
How do you store a feed’s packages and versions in an optimal
way?
Three important values: feed name, package id, package version
Table per feed
Package id = PartitionKey
Package version = RowKey
Storage
Reading 1.000 rows and deserializing them is SLOW (many
seconds)
We cache some tables on blob storage
1.000 rows in serialized JSON = small
Loading one file over HTTP = fast
Searching in memory through 1.000 rows = fast
Cache update subscribed to IEvent
Multi-tenancy
How to bring this into code
Just like Request, Response and User:
a Tenant is contextual
All those are potentially different for every
request
DI containers with lifetimes exist…
Resolving a tenant
public interface ITenantContext {
Tenant Tenant { get; }
}
// Registration in container
builder.RegisterType<RequestTenantContext>()
.As<ITenantContext>().InstancePerLifetimeScope();
public class RequestTenantContext {
public Tenant Resolve(RequestContext context, IEnumerable<Tenant> tenants) {
var hostname = context.HttpContext.Request.Url.Host;
return tenants.FirstOrDefault(t => t.HostName == hostname);
}
}
Windows Azure
Access Control Service
Imagine managing this!
Multiple applications
www.myget.org
staging.myget.org
localhost:1196
Customer1.myget.org
Customer2.myget.org
…
Multiple identity providers
Who wants Microsoft Account?
Google anyone?
Oh, your custom ADFS? Sure!
ACS = identity orchestration
ACS for MyGet
No more user registration
One single trust relationship (= less coding)
Microsoft Account, Yahoo!, Google, Facebook
Other IdP’s (tenants and our own)*
*We built many others and are working on a spin-off
http://socialsts.com (Twitter, LinkedIn, Microsoft Account, …)
One small trick…
var realm = TenantContext.Tenant.Realm;
var allowedAudienceUris = FederatedAuthentication.FederationConfiguration
.IdentityConfiguration
.AudienceRestriction
.AllowedAudienceUris;
if (allowedAudienceUris.All(
audience => audience.ToString() != TenantContext.Tenant.Realm))
{
allowedAudienceUris.Add(new Uri(TenantContext.Tenant.Realm));
}
Tough times
(learning moments)
Huge downtime on July 2nd, 2012
Symptoms:
Users complaining about “downtime”
No monitoring SMS alert
Half an hour later: “site up!”, “site down!”, “site up!”, “site down!” SMS alerts
No sign of issues in the Windows Azure Management portal
But what’s the cause?
We just deployed our multi-tenant architecture
We just enabled storage analytics
ELMAH was showing storage throttling
16.000 unprocessed commands and events in queue
Full story at http://blog.myget.org/post/2012/07/02/Site-issues-on-July-2nd-2012.aspx
Huge downtime on July 2nd, 2012
One, simple piece of code…
GetHashCode() on Package object faulty
GetHashCode() used to track object in data context (new vs. update)
2 objects with the same hashcode = UnhandledException
Full story at http://blog.myget.org/post/2012/07/02/Site-issues-on-July-2nd-2012.aspx
An exception killed the site? WTF?!?
No. We caught any Exception and back then, blindly retry operations
Resulting in 16.000 commands and events being retried continuously
Causing storage throttling
Causing the website to retry reads
Causing more throttling
Starving IIS worker threads
Lessons learned?
A simple bug can halt the entire application
Only retry transient errors
Our monitoring wasn’t optimal
Our code wasn’t optimal (code from back when MyGet was a blog post…)
Huge downtime February 23rd, 2013
Symptoms:
Everything down
Furious users on social media
Windows Azure Management Portal Down
Furious tweets about #WindowsAzure
The cause?
Global outage of Windows Azure due to an expired SSL certificate on
storage
Full story at http://blog.myget.org/post/2013/02/24/We-were-down.aspx
Considerations and lessons learned
Move storage to HTTP instead of HTTPS?
Windows Azure down globally impacts us quite a bit
Fail-over to another solution costs money and lots of effort
Decided against it for now
Considering off-Windows Azure backups of at least all packages
Full story at http://blog.myget.org/post/2013/02/24/We-were-down.aspx
One more! New features…
“Retention policies” introduced
Seemed to be a success!
3+ million commands and events in queue
Solution: scale out
20 instances did it in a few minutes
Solution for the future: feature toggling
But overall…
When business
meets technology
We’re constantly being bitten
Introduce a new beta feature
Come up with a revenue model
See the feature needs serious rewriting (metering)
Lesson learned? Think revenue early on.
Measure everything, test assumptions
“The Lean Startup” book says this
Don’t build it yourself: Google Analytics
this is why we built username/password registration,
seems a lot of people prefer typing instead of one clic
we must keep investing in Build Services
feed discovery is more popular than we imagined
from zero reactions on our blog and Twitter
the technical fear we had about “download as
ZIP” consuming too much server resources?
Seems 19 people used it this month. *yawn*
Conclusion
Conclusion
NuGet? MyGet?
How we started
What we did not know
Our architecture
Multi-tenancy
Though times provide learning
Measurement too
http://blog.maartenballiauw.be
@maartenballiauw
http://amzn.to/pronuget
http://www.myget.org

Más contenido relacionado

La actualidad más candente

Nodejs Event Driven Concurrency for Web Applications
Nodejs Event Driven Concurrency for Web ApplicationsNodejs Event Driven Concurrency for Web Applications
Nodejs Event Driven Concurrency for Web ApplicationsGanesh Iyer
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...Tom Croucher
 
NodeJS ecosystem
NodeJS ecosystemNodeJS ecosystem
NodeJS ecosystemYukti Kaura
 
Java script at backend nodejs
Java script at backend   nodejsJava script at backend   nodejs
Java script at backend nodejsAmit Thakkar
 
Production Debugging War Stories
Production Debugging War StoriesProduction Debugging War Stories
Production Debugging War StoriesIdo Flatow
 
What is Google Cloud Good For at DevFestInspire 2021
What is Google Cloud Good For at DevFestInspire 2021What is Google Cloud Good For at DevFestInspire 2021
What is Google Cloud Good For at DevFestInspire 2021Robert John
 
Hug #9 who's keeping your secrets
Hug #9 who's keeping your secretsHug #9 who's keeping your secrets
Hug #9 who's keeping your secretsCameron More
 
Prometheus: From technical metrics to business observability
Prometheus: From technical metrics to business observabilityPrometheus: From technical metrics to business observability
Prometheus: From technical metrics to business observabilityJulien Pivotto
 
Building ‘Bootiful’ microservices cloud
Building ‘Bootiful’ microservices cloudBuilding ‘Bootiful’ microservices cloud
Building ‘Bootiful’ microservices cloudIdan Fridman
 
Introduction to node.js aka NodeJS
Introduction to node.js aka NodeJSIntroduction to node.js aka NodeJS
Introduction to node.js aka NodeJSJITENDRA KUMAR PATEL
 
Event Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikEvent Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikIlya Grigorik
 
Vincenzo Chianese - REST, for real! - Codemotion Milan 2017
Vincenzo Chianese - REST, for real! - Codemotion Milan 2017Vincenzo Chianese - REST, for real! - Codemotion Milan 2017
Vincenzo Chianese - REST, for real! - Codemotion Milan 2017Codemotion
 
Building a production ready meteor app
Building a production ready meteor appBuilding a production ready meteor app
Building a production ready meteor appRitik Malhotra
 
Devoxx France: Fault tolerant microservices on the JVM with Cassandra
Devoxx France: Fault tolerant microservices on the JVM with CassandraDevoxx France: Fault tolerant microservices on the JVM with Cassandra
Devoxx France: Fault tolerant microservices on the JVM with CassandraChristopher Batey
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.jsJack Franklin
 
Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Dinh Pham
 

La actualidad más candente (20)

Nodejs Event Driven Concurrency for Web Applications
Nodejs Event Driven Concurrency for Web ApplicationsNodejs Event Driven Concurrency for Web Applications
Nodejs Event Driven Concurrency for Web Applications
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...
 
NodeJS ecosystem
NodeJS ecosystemNodeJS ecosystem
NodeJS ecosystem
 
Java script at backend nodejs
Java script at backend   nodejsJava script at backend   nodejs
Java script at backend nodejs
 
Production Debugging War Stories
Production Debugging War StoriesProduction Debugging War Stories
Production Debugging War Stories
 
Best node js course
Best node js courseBest node js course
Best node js course
 
Node.js
Node.jsNode.js
Node.js
 
What is Google Cloud Good For at DevFestInspire 2021
What is Google Cloud Good For at DevFestInspire 2021What is Google Cloud Good For at DevFestInspire 2021
What is Google Cloud Good For at DevFestInspire 2021
 
Hug #9 who's keeping your secrets
Hug #9 who's keeping your secretsHug #9 who's keeping your secrets
Hug #9 who's keeping your secrets
 
Prometheus: From technical metrics to business observability
Prometheus: From technical metrics to business observabilityPrometheus: From technical metrics to business observability
Prometheus: From technical metrics to business observability
 
Building ‘Bootiful’ microservices cloud
Building ‘Bootiful’ microservices cloudBuilding ‘Bootiful’ microservices cloud
Building ‘Bootiful’ microservices cloud
 
Node js for beginners
Node js for beginnersNode js for beginners
Node js for beginners
 
NodeJS: an Introduction
NodeJS: an IntroductionNodeJS: an Introduction
NodeJS: an Introduction
 
Introduction to node.js aka NodeJS
Introduction to node.js aka NodeJSIntroduction to node.js aka NodeJS
Introduction to node.js aka NodeJS
 
Event Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya GrigorikEvent Driven Architecture - MeshU - Ilya Grigorik
Event Driven Architecture - MeshU - Ilya Grigorik
 
Vincenzo Chianese - REST, for real! - Codemotion Milan 2017
Vincenzo Chianese - REST, for real! - Codemotion Milan 2017Vincenzo Chianese - REST, for real! - Codemotion Milan 2017
Vincenzo Chianese - REST, for real! - Codemotion Milan 2017
 
Building a production ready meteor app
Building a production ready meteor appBuilding a production ready meteor app
Building a production ready meteor app
 
Devoxx France: Fault tolerant microservices on the JVM with Cassandra
Devoxx France: Fault tolerant microservices on the JVM with CassandraDevoxx France: Fault tolerant microservices on the JVM with Cassandra
Devoxx France: Fault tolerant microservices on the JVM with Cassandra
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?
 

Similar a How it's made - MyGet (CloudBurst)

Beginning MEAN Stack
Beginning MEAN StackBeginning MEAN Stack
Beginning MEAN StackRob Davarnia
 
Production debugging web applications
Production debugging web applicationsProduction debugging web applications
Production debugging web applicationsIdo Flatow
 
Why Wordnik went non-relational
Why Wordnik went non-relationalWhy Wordnik went non-relational
Why Wordnik went non-relationalTony Tam
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - TalkMatthias Noback
 
DOs and DONTs on the way to 10M users
DOs and DONTs on the way to 10M usersDOs and DONTs on the way to 10M users
DOs and DONTs on the way to 10M usersYoav Avrahami
 
2016_04_04_CNI_Spring_Meeting_Microservices
2016_04_04_CNI_Spring_Meeting_Microservices2016_04_04_CNI_Spring_Meeting_Microservices
2016_04_04_CNI_Spring_Meeting_MicroservicesJason Varghese
 
Building a Global-Scale Multi-Tenant Cloud Platform on AWS and Docker: Lesson...
Building a Global-Scale Multi-Tenant Cloud Platform on AWS and Docker: Lesson...Building a Global-Scale Multi-Tenant Cloud Platform on AWS and Docker: Lesson...
Building a Global-Scale Multi-Tenant Cloud Platform on AWS and Docker: Lesson...Felix Gessert
 
Reducing latency on the web with the Azure CDN - DevSum - SWAG
Reducing latency on the web with the Azure CDN - DevSum - SWAGReducing latency on the web with the Azure CDN - DevSum - SWAG
Reducing latency on the web with the Azure CDN - DevSum - SWAGMaarten Balliauw
 
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)Maarten Balliauw
 
Building Applications With the MEAN Stack
Building Applications With the MEAN StackBuilding Applications With the MEAN Stack
Building Applications With the MEAN StackNir Noy
 
Microservices , Docker , CI/CD , Kubernetes Seminar - Sri Lanka
Microservices , Docker , CI/CD , Kubernetes Seminar - Sri Lanka Microservices , Docker , CI/CD , Kubernetes Seminar - Sri Lanka
Microservices , Docker , CI/CD , Kubernetes Seminar - Sri Lanka Mario Ishara Fernando
 
Why Reactive Architecture Will Take Over The World (and why we should be wary...
Why Reactive Architecture Will Take Over The World (and why we should be wary...Why Reactive Architecture Will Take Over The World (and why we should be wary...
Why Reactive Architecture Will Take Over The World (and why we should be wary...Steve Pember
 
Node.js Enterprise Middleware
Node.js Enterprise MiddlewareNode.js Enterprise Middleware
Node.js Enterprise MiddlewareBehrad Zari
 
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010Bhupesh Bansal
 
Hadoop and Voldemort @ LinkedIn
Hadoop and Voldemort @ LinkedInHadoop and Voldemort @ LinkedIn
Hadoop and Voldemort @ LinkedInHadoop User Group
 
GlobalsDB: Its significance for Node.js Developers
GlobalsDB: Its significance for Node.js DevelopersGlobalsDB: Its significance for Node.js Developers
GlobalsDB: Its significance for Node.js DevelopersRob Tweed
 
Lessons learned from writing over 300,000 lines of infrastructure code
Lessons learned from writing over 300,000 lines of infrastructure codeLessons learned from writing over 300,000 lines of infrastructure code
Lessons learned from writing over 300,000 lines of infrastructure codeYevgeniy Brikman
 
Distributed Reactive Architecture: Extending SOA with Events
Distributed Reactive Architecture: Extending SOA with EventsDistributed Reactive Architecture: Extending SOA with Events
Distributed Reactive Architecture: Extending SOA with EventsSteve Pember
 
ArcReady - Architecting For The Cloud
ArcReady - Architecting For The CloudArcReady - Architecting For The Cloud
ArcReady - Architecting For The CloudMicrosoft ArcReady
 
Making it fast: Zotonic & Performance
Making it fast: Zotonic & PerformanceMaking it fast: Zotonic & Performance
Making it fast: Zotonic & PerformanceArjan
 

Similar a How it's made - MyGet (CloudBurst) (20)

Beginning MEAN Stack
Beginning MEAN StackBeginning MEAN Stack
Beginning MEAN Stack
 
Production debugging web applications
Production debugging web applicationsProduction debugging web applications
Production debugging web applications
 
Why Wordnik went non-relational
Why Wordnik went non-relationalWhy Wordnik went non-relational
Why Wordnik went non-relational
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
DOs and DONTs on the way to 10M users
DOs and DONTs on the way to 10M usersDOs and DONTs on the way to 10M users
DOs and DONTs on the way to 10M users
 
2016_04_04_CNI_Spring_Meeting_Microservices
2016_04_04_CNI_Spring_Meeting_Microservices2016_04_04_CNI_Spring_Meeting_Microservices
2016_04_04_CNI_Spring_Meeting_Microservices
 
Building a Global-Scale Multi-Tenant Cloud Platform on AWS and Docker: Lesson...
Building a Global-Scale Multi-Tenant Cloud Platform on AWS and Docker: Lesson...Building a Global-Scale Multi-Tenant Cloud Platform on AWS and Docker: Lesson...
Building a Global-Scale Multi-Tenant Cloud Platform on AWS and Docker: Lesson...
 
Reducing latency on the web with the Azure CDN - DevSum - SWAG
Reducing latency on the web with the Azure CDN - DevSum - SWAGReducing latency on the web with the Azure CDN - DevSum - SWAG
Reducing latency on the web with the Azure CDN - DevSum - SWAG
 
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)
 
Building Applications With the MEAN Stack
Building Applications With the MEAN StackBuilding Applications With the MEAN Stack
Building Applications With the MEAN Stack
 
Microservices , Docker , CI/CD , Kubernetes Seminar - Sri Lanka
Microservices , Docker , CI/CD , Kubernetes Seminar - Sri Lanka Microservices , Docker , CI/CD , Kubernetes Seminar - Sri Lanka
Microservices , Docker , CI/CD , Kubernetes Seminar - Sri Lanka
 
Why Reactive Architecture Will Take Over The World (and why we should be wary...
Why Reactive Architecture Will Take Over The World (and why we should be wary...Why Reactive Architecture Will Take Over The World (and why we should be wary...
Why Reactive Architecture Will Take Over The World (and why we should be wary...
 
Node.js Enterprise Middleware
Node.js Enterprise MiddlewareNode.js Enterprise Middleware
Node.js Enterprise Middleware
 
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010
 
Hadoop and Voldemort @ LinkedIn
Hadoop and Voldemort @ LinkedInHadoop and Voldemort @ LinkedIn
Hadoop and Voldemort @ LinkedIn
 
GlobalsDB: Its significance for Node.js Developers
GlobalsDB: Its significance for Node.js DevelopersGlobalsDB: Its significance for Node.js Developers
GlobalsDB: Its significance for Node.js Developers
 
Lessons learned from writing over 300,000 lines of infrastructure code
Lessons learned from writing over 300,000 lines of infrastructure codeLessons learned from writing over 300,000 lines of infrastructure code
Lessons learned from writing over 300,000 lines of infrastructure code
 
Distributed Reactive Architecture: Extending SOA with Events
Distributed Reactive Architecture: Extending SOA with EventsDistributed Reactive Architecture: Extending SOA with Events
Distributed Reactive Architecture: Extending SOA with Events
 
ArcReady - Architecting For The Cloud
ArcReady - Architecting For The CloudArcReady - Architecting For The Cloud
ArcReady - Architecting For The Cloud
 
Making it fast: Zotonic & Performance
Making it fast: Zotonic & PerformanceMaking it fast: Zotonic & Performance
Making it fast: Zotonic & Performance
 

Más de Maarten Balliauw

Bringing nullability into existing code - dammit is not the answer.pptx
Bringing nullability into existing code - dammit is not the answer.pptxBringing nullability into existing code - dammit is not the answer.pptx
Bringing nullability into existing code - dammit is not the answer.pptxMaarten Balliauw
 
Nerd sniping myself into a rabbit hole... Streaming online audio to a Sonos s...
Nerd sniping myself into a rabbit hole... Streaming online audio to a Sonos s...Nerd sniping myself into a rabbit hole... Streaming online audio to a Sonos s...
Nerd sniping myself into a rabbit hole... Streaming online audio to a Sonos s...Maarten Balliauw
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceMaarten Balliauw
 
Microservices for building an IDE - The innards of JetBrains Rider - NDC Oslo...
Microservices for building an IDE - The innards of JetBrains Rider - NDC Oslo...Microservices for building an IDE - The innards of JetBrains Rider - NDC Oslo...
Microservices for building an IDE - The innards of JetBrains Rider - NDC Oslo...Maarten Balliauw
 
Indexing and searching NuGet.org with Azure Functions and Search - .NET fwday...
Indexing and searching NuGet.org with Azure Functions and Search - .NET fwday...Indexing and searching NuGet.org with Azure Functions and Search - .NET fwday...
Indexing and searching NuGet.org with Azure Functions and Search - .NET fwday...Maarten Balliauw
 
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...Maarten Balliauw
 
JetBrains Australia 2019 - Exploring .NET’s memory management – a trip down m...
JetBrains Australia 2019 - Exploring .NET’s memory management – a trip down m...JetBrains Australia 2019 - Exploring .NET’s memory management – a trip down m...
JetBrains Australia 2019 - Exploring .NET’s memory management – a trip down m...Maarten Balliauw
 
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se....NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...Maarten Balliauw
 
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...Maarten Balliauw
 
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and SearchNDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and SearchMaarten Balliauw
 
Approaches for application request throttling - Cloud Developer Days Poland
Approaches for application request throttling - Cloud Developer Days PolandApproaches for application request throttling - Cloud Developer Days Poland
Approaches for application request throttling - Cloud Developer Days PolandMaarten Balliauw
 
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...Maarten Balliauw
 
Approaches for application request throttling - dotNetCologne
Approaches for application request throttling - dotNetCologneApproaches for application request throttling - dotNetCologne
Approaches for application request throttling - dotNetCologneMaarten Balliauw
 
CodeStock - Exploring .NET memory management - a trip down memory lane
CodeStock - Exploring .NET memory management - a trip down memory laneCodeStock - Exploring .NET memory management - a trip down memory lane
CodeStock - Exploring .NET memory management - a trip down memory laneMaarten Balliauw
 
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...Maarten Balliauw
 
ConFoo Montreal - Approaches for application request throttling
ConFoo Montreal - Approaches for application request throttlingConFoo Montreal - Approaches for application request throttling
ConFoo Montreal - Approaches for application request throttlingMaarten Balliauw
 
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...Maarten Balliauw
 
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...Maarten Balliauw
 
DotNetFest - Let’s refresh our memory! Memory management in .NET
DotNetFest - Let’s refresh our memory! Memory management in .NETDotNetFest - Let’s refresh our memory! Memory management in .NET
DotNetFest - Let’s refresh our memory! Memory management in .NETMaarten Balliauw
 
VISUG - Approaches for application request throttling
VISUG - Approaches for application request throttlingVISUG - Approaches for application request throttling
VISUG - Approaches for application request throttlingMaarten Balliauw
 

Más de Maarten Balliauw (20)

Bringing nullability into existing code - dammit is not the answer.pptx
Bringing nullability into existing code - dammit is not the answer.pptxBringing nullability into existing code - dammit is not the answer.pptx
Bringing nullability into existing code - dammit is not the answer.pptx
 
Nerd sniping myself into a rabbit hole... Streaming online audio to a Sonos s...
Nerd sniping myself into a rabbit hole... Streaming online audio to a Sonos s...Nerd sniping myself into a rabbit hole... Streaming online audio to a Sonos s...
Nerd sniping myself into a rabbit hole... Streaming online audio to a Sonos s...
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
 
Microservices for building an IDE - The innards of JetBrains Rider - NDC Oslo...
Microservices for building an IDE - The innards of JetBrains Rider - NDC Oslo...Microservices for building an IDE - The innards of JetBrains Rider - NDC Oslo...
Microservices for building an IDE - The innards of JetBrains Rider - NDC Oslo...
 
Indexing and searching NuGet.org with Azure Functions and Search - .NET fwday...
Indexing and searching NuGet.org with Azure Functions and Search - .NET fwday...Indexing and searching NuGet.org with Azure Functions and Search - .NET fwday...
Indexing and searching NuGet.org with Azure Functions and Search - .NET fwday...
 
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...
 
JetBrains Australia 2019 - Exploring .NET’s memory management – a trip down m...
JetBrains Australia 2019 - Exploring .NET’s memory management – a trip down m...JetBrains Australia 2019 - Exploring .NET’s memory management – a trip down m...
JetBrains Australia 2019 - Exploring .NET’s memory management – a trip down m...
 
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se....NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...
 
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
 
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and SearchNDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
 
Approaches for application request throttling - Cloud Developer Days Poland
Approaches for application request throttling - Cloud Developer Days PolandApproaches for application request throttling - Cloud Developer Days Poland
Approaches for application request throttling - Cloud Developer Days Poland
 
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
 
Approaches for application request throttling - dotNetCologne
Approaches for application request throttling - dotNetCologneApproaches for application request throttling - dotNetCologne
Approaches for application request throttling - dotNetCologne
 
CodeStock - Exploring .NET memory management - a trip down memory lane
CodeStock - Exploring .NET memory management - a trip down memory laneCodeStock - Exploring .NET memory management - a trip down memory lane
CodeStock - Exploring .NET memory management - a trip down memory lane
 
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
 
ConFoo Montreal - Approaches for application request throttling
ConFoo Montreal - Approaches for application request throttlingConFoo Montreal - Approaches for application request throttling
ConFoo Montreal - Approaches for application request throttling
 
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
 
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
 
DotNetFest - Let’s refresh our memory! Memory management in .NET
DotNetFest - Let’s refresh our memory! Memory management in .NETDotNetFest - Let’s refresh our memory! Memory management in .NET
DotNetFest - Let’s refresh our memory! Memory management in .NET
 
VISUG - Approaches for application request throttling
VISUG - Approaches for application request throttlingVISUG - Approaches for application request throttling
VISUG - Approaches for application request throttling
 

Último

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 

Último (20)

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 

How it's made - MyGet (CloudBurst)

  • 1. How it’s made: MyGet Maarten Balliauw @maartenballiauw
  • 2. Who am I? Maarten Balliauw Daytime: Technical Evangelist, JetBrains Co-founder of MyGet Author – Pro NuGet http://amzn.to/pronuget AZUG Focus on web ASP.NET MVC, Windows Azure, SignalR, ... MVP Windows Azure & ASPInsider http://blog.maartenballiauw.be @maartenballiauw
  • 3. Who am I? Maarten Balliauw Daytime: Technical Evangelist, JetBrains Co-founder of MyGet Author – Pro NuGet http://amzn.to/pronuget AZUG Focus on web ASP.NET MVC, Windows Azure, SignalR, ... MVP Windows Azure & ASPInsider http://blog.maartenballiauw.be @maartenballiauw
  • 4. Who am I? Maarten Balliauw Daytime: Technical Evangelist, JetBrains Co-founder of MyGet Author – Pro NuGet http://amzn.to/pronuget AZUG Focus on web ASP.NET MVC, Windows Azure, SignalR, ... MVP Windows Azure & ASPInsider http://blog.maartenballiauw.be @maartenballiauw
  • 5. Agenda NuGet? MyGet? How we started What we did not know Our first architecture Our second architecture Multi-tenancy ACS Tough times (learning moments) When business meets technology Conclusion
  • 9. Why MyGet? Safely store your IP with us Creating packages is hard. We have Build Services! Granular security Activity streams Symbol server Analytics
  • 10. I’m not alone! Xavier Decoster @xavierdecoster Yves Goeleven @yvesgoeleven Also known as @MyGetTeam
  • 12. The real begin? May 09, 2011
  • 13. NuPack! Using OData as their feeds Which is some sort of WCF… Multiple feeds? Exchanged some ideas with Xavier Prototyped something during TechDays Belgium, 2011
  • 15. Technologies used? Windows Azure Windows Azure Table Storage & Blob Storage Windows Azure ACS (no way I’m typing another user registration) ASP.NET MVC 2 MEF
  • 16. Here’s some code from back then… [Authorize] public class FeedController : Controller { public ActionResult List() { var privateFeedTable = PrivateFeedTable.Create(); var privateFeeds = privateFeedTable.GetAll( f => f.PartitionKey == User.Identity.Name.ToBase64()); var model = new PrivateFeedListViewModel(); foreach (var privateFeed in privateFeeds.Where(f => f.IsVisible)) { var privateFeedViewModel = new PrivateFeedViewModel(); model.Items.Add(AutoMapper.Mapper.Map(privateFeed, privateFeedViewModel)); } return View(model);
  • 17. How about this one? try { privateFeedNuGetPackageTable.Add(privateFeedPackage); } catch { // Omnomnom! }
  • 18. Best practices used back then?
  • 19. Architecture at the time? Cloud Services: one web role doing all work Storage: one storage account Windows Azure Access Control Service
  • 20. What we did not know…
  • 21. Users would come! Grew from 5 feeds to 70 feeds in a few weeks 10 feeds per week added thereafter
  • 22. Data would come! One user pushed 1.300 packages worth 1 GB of storage Others started pushing CI packages Others seemed to be copying www.nuget.org
  • 24. ReSharper time! A lot of refactoring done Direct data access -> repositories Repositories used by services Services used by controllers Using best practices SOLID and DRY (well, not everywhere but refactoring takes time) Running on two instances (availability, yay!)
  • 25. We became a startup Someone mentioned they would pay for our service Think about business model Volume of feeds and packages kept going up Users in EU and US
  • 29. Not so awesome… Best practices! Are they? Layers! No spaghetti code but lasagna code Typical business application architecture! Proved to be very inflexible
  • 30. Our first architecture - infrastructure
  • 31. Awesome! Datacenters nearby our users Centralizes storage Packages on CDN for faster throughput DNS fail-over if one of the DC’s went down
  • 32. No so awesome… Datacenters nearby our users Or not? Centralizes storage Speed of light! USA was slow! Packages on CDN for faster throughput Sync issues, downtime, … DNS fail-over if one of the DC’s went down Seems not every ISP follows DNS standards
  • 33. We persisted! Local caching in USA added 2 instances in EU, 3 in the USA Speed of light! Syncing all data kept being slow Populating cache was a nightmare CDN kept having issues Of 3 instances, only 1 was being used with enough load (60%)
  • 34. We were growing! We had public subscription plans We added enterprise tenants (multi-tenancy added) Resulting in… Architecture became complex Caching and syncing became complex
  • 37. We had a look at our workloads Managing feeds and packages Doesn’t matter much where (sync vs. bandwidth) Downloading packages May matter where, let the tenant decide Builds Who cares where!
  • 38. Our 2nd architecture - infrastructure
  • 40. Our first architecture… … was scaled across the globe … but as synchronous as it could be … prone to all issues with latency vs. synchrony Event Driven Architecture?* *disclaimer: we borrowed some concepts from EDA
  • 41. EDA in MyGet Some actions put an ICommand on a queue (ground rule: if it can’t be done in 1 write, use ICommand) All actions complete with an IEvent on a queue Handlers can subscribe to ICommand and IEvent Handlers are idempotent and not depending on others
  • 42. Example: log in 2 operations: 1 read, 1 write Read the profile Store the profile with LastLogin date No use of ICommand Finishes with UserLoggedInEvent
  • 43. Example: change feed owner Many operations! Read two user profiles Read current access rights Change access rights Push new privileges to SymbolSource.org One command, one event ChangeFeedOwnerCommand FeedOwnerChangedEvent
  • 45. Gain? We now run on 2 instances, mostly for redundancy Average CPU usage? 20% (across machines) Flexibility! Way easier to implement new features! New feature: activity log Simply subscribe to events we want to see in that log
  • 46. Storage No relational database (why not?) Event-driven architecture How do you store a feed’s packages and versions in an optimal way? Three important values: feed name, package id, package version Table per feed Package id = PartitionKey Package version = RowKey
  • 47. Storage Reading 1.000 rows and deserializing them is SLOW (many seconds) We cache some tables on blob storage 1.000 rows in serialized JSON = small Loading one file over HTTP = fast Searching in memory through 1.000 rows = fast Cache update subscribed to IEvent
  • 49. How to bring this into code Just like Request, Response and User: a Tenant is contextual All those are potentially different for every request DI containers with lifetimes exist…
  • 50. Resolving a tenant public interface ITenantContext { Tenant Tenant { get; } } // Registration in container builder.RegisterType<RequestTenantContext>() .As<ITenantContext>().InstancePerLifetimeScope(); public class RequestTenantContext { public Tenant Resolve(RequestContext context, IEnumerable<Tenant> tenants) { var hostname = context.HttpContext.Request.Url.Host; return tenants.FirstOrDefault(t => t.HostName == hostname); } }
  • 52. Imagine managing this! Multiple applications www.myget.org staging.myget.org localhost:1196 Customer1.myget.org Customer2.myget.org … Multiple identity providers Who wants Microsoft Account? Google anyone? Oh, your custom ADFS? Sure!
  • 53. ACS = identity orchestration
  • 54. ACS for MyGet No more user registration One single trust relationship (= less coding) Microsoft Account, Yahoo!, Google, Facebook Other IdP’s (tenants and our own)* *We built many others and are working on a spin-off http://socialsts.com (Twitter, LinkedIn, Microsoft Account, …)
  • 55. One small trick… var realm = TenantContext.Tenant.Realm; var allowedAudienceUris = FederatedAuthentication.FederationConfiguration .IdentityConfiguration .AudienceRestriction .AllowedAudienceUris; if (allowedAudienceUris.All( audience => audience.ToString() != TenantContext.Tenant.Realm)) { allowedAudienceUris.Add(new Uri(TenantContext.Tenant.Realm)); }
  • 57. Huge downtime on July 2nd, 2012 Symptoms: Users complaining about “downtime” No monitoring SMS alert Half an hour later: “site up!”, “site down!”, “site up!”, “site down!” SMS alerts No sign of issues in the Windows Azure Management portal But what’s the cause? We just deployed our multi-tenant architecture We just enabled storage analytics ELMAH was showing storage throttling 16.000 unprocessed commands and events in queue Full story at http://blog.myget.org/post/2012/07/02/Site-issues-on-July-2nd-2012.aspx
  • 58. Huge downtime on July 2nd, 2012 One, simple piece of code… GetHashCode() on Package object faulty GetHashCode() used to track object in data context (new vs. update) 2 objects with the same hashcode = UnhandledException Full story at http://blog.myget.org/post/2012/07/02/Site-issues-on-July-2nd-2012.aspx
  • 59. An exception killed the site? WTF?!? No. We caught any Exception and back then, blindly retry operations Resulting in 16.000 commands and events being retried continuously Causing storage throttling Causing the website to retry reads Causing more throttling Starving IIS worker threads Lessons learned? A simple bug can halt the entire application Only retry transient errors Our monitoring wasn’t optimal Our code wasn’t optimal (code from back when MyGet was a blog post…)
  • 60. Huge downtime February 23rd, 2013 Symptoms: Everything down Furious users on social media Windows Azure Management Portal Down Furious tweets about #WindowsAzure The cause? Global outage of Windows Azure due to an expired SSL certificate on storage Full story at http://blog.myget.org/post/2013/02/24/We-were-down.aspx
  • 61. Considerations and lessons learned Move storage to HTTP instead of HTTPS? Windows Azure down globally impacts us quite a bit Fail-over to another solution costs money and lots of effort Decided against it for now Considering off-Windows Azure backups of at least all packages Full story at http://blog.myget.org/post/2013/02/24/We-were-down.aspx
  • 62. One more! New features… “Retention policies” introduced Seemed to be a success! 3+ million commands and events in queue Solution: scale out 20 instances did it in a few minutes Solution for the future: feature toggling
  • 65. We’re constantly being bitten Introduce a new beta feature Come up with a revenue model See the feature needs serious rewriting (metering) Lesson learned? Think revenue early on.
  • 66. Measure everything, test assumptions “The Lean Startup” book says this Don’t build it yourself: Google Analytics
  • 67. this is why we built username/password registration, seems a lot of people prefer typing instead of one clic we must keep investing in Build Services feed discovery is more popular than we imagined from zero reactions on our blog and Twitter the technical fear we had about “download as ZIP” consuming too much server resources? Seems 19 people used it this month. *yawn*
  • 69. Conclusion NuGet? MyGet? How we started What we did not know Our architecture Multi-tenancy Though times provide learning Measurement too

Notas del editor

  1. Maarten
  2. Maarten
  3. Maarten