In this session we will explore several modeling scenarios from my own experience that can easily be achieved using RavenDB, but difficult (if not nearly impossible) to build using a classic relational database. The focus will be on helping those accustomed to SQL Server or other relational databases learn good document modeling skills by example, with a summary of document modeling guidelines at the end.
We describe the features of Oak Lucene indexes and how they can be used to get your queries perform better. In the second part we will talk about how asynchronous indexing works in general and how it can be monitored.
This was presented as part of AEM Gem Series -http://dev.day.com/content/ddc/en/gems/oak-lucene-indexes.html
Elasticsearch - Devoxx France 2012 - English versionDavid Pilato
Elasticsearch presentation for Devoxx France 2012
English translation (feel free to correct my bad english ;-) )
French version is available here : http://www.slideshare.net/dadoonet/elasticsearch-devoxx-france-2012
This is an introductory presentation to Cassandra, the database of choice for high availability and insane scalability.
I gave this talk at TheEdge conference.
This was my entities and fields presentation from Drupalcamp Colorado 2020.
http://drupalcampcolorado.org/sessions/drupal-7-entities-and-fields-transitioning-d7
We describe the features of Oak Lucene indexes and how they can be used to get your queries perform better. In the second part we will talk about how asynchronous indexing works in general and how it can be monitored.
This was presented as part of AEM Gem Series -http://dev.day.com/content/ddc/en/gems/oak-lucene-indexes.html
Elasticsearch - Devoxx France 2012 - English versionDavid Pilato
Elasticsearch presentation for Devoxx France 2012
English translation (feel free to correct my bad english ;-) )
French version is available here : http://www.slideshare.net/dadoonet/elasticsearch-devoxx-france-2012
This is an introductory presentation to Cassandra, the database of choice for high availability and insane scalability.
I gave this talk at TheEdge conference.
This was my entities and fields presentation from Drupalcamp Colorado 2020.
http://drupalcampcolorado.org/sessions/drupal-7-entities-and-fields-transitioning-d7
How can we harness AEM6 and Sling to integrate backed layers to the CMS and expose them as a unified framework. creation of these integrations is vital for a coherent, personalize-able and track-able sites.
Akka is using the Actors together with STM to create a unified runtime and programming model for scaling both UP (multi-core) and OUT (grid/cloud). Akka provides location transparency by abstracting away both these tangents of scalability by turning them into an ops task. This gives the Akka runtime freedom to do adaptive automatic load-balancing, cluster rebalancing, replication & partitioning
Synthetic Models are not a new concept – but the concept is rarely used when developing in AEM/Sling/JCR.
They
Define domain objects where the domain is not exclusive to the content repository
Their property collection is defined against the data from each data source
Must be orchestrated by Sling’s resource resolution mechanism
Leverage the Presentation Model design pattern
Name is inspired by the SyntheticResource class
This definition came out of several past experiences where data from external sources was required to be brought into AEM and exposed to the presentation layer as if it was content.
Also through research on the problem I cam upon the SyntheticResource class. Think of it as the lesser-known cousin of Resource. It is often used to define resource objects that don’t exist in the JCR content tree or resources that are created at run-time
Building Reactive Systems with Akka (in Java 8 or Scala)Jonas Bonér
Learn how to build Reactive Systems with Akka. Examples in both Java 8 and Scala.
Abstract:
The demands and expectations for applications have changed dramatically in recent years. Applications today are deployed on a wide range of infrastructure; from mobile devices up to thousands of nodes running in the cloud—all powered by multi-core processors. They need to be rich and collaborative, have a real-time feel with millisecond response time and should never stop running. Additionally, modern applications are a mashup of external services that need to be consumed and composed to provide the features at hand. We are seeing a new type of applications emerging to address these new challenges—these are being called Reactive Applications.
In this talk we will introduce you to Akka and discuss how it can help you deliver on the four key traits of Reactive; Responsive, Resilient, Elastic and Message-Driven. We will start with the basics of Akka and work our way towards some of its more advanced modules such as Akka Cluster and Akka Persistence—all driven through code and practical examples.
Lessons learned from years of maintaining/extending/improving an in house CMS. Hopefully these will present things to avoid and things to try that will save others some pain.
This presentation explains what Computer Science actually entails. It covers ways to describe code performance using Big-Oh notation comparing different post meta and taxonomy queries and it discusses concurrency as it applies to WordPress, specifically data races and how they can occur while counting post views.
A deep dive into the inner workings of ClojureScript's analysis,
88 compilation, and runtime phases. The talk focused specifically on
89 the way that traditional JavaScript abstractions thwart code-size
90 and efficiency and how ClojureScript avoids such pitfalls. Finally,
91 I told a couple "war stories" about some of the specific challenges
92 met by the Clojure/core team during the development of the compiler
93 and runtime.
Supercharging WordPress Development in 2018Adam Tomat
Slide links:
- PHP-FIG: https://www.php-fig.org/psr
- Timber: https://www.upstatement.com/timber/
- Bedrock: https://roots.io/bedrock/
- Lumberjack: https://github.com/Rareloop/lumberjack
- Lumberjack Core: https://github.com/Rareloop/lumberjack-core
- Collections: https://laravel.com/docs/5.6/collections
- PHP-DI: http://php-di.org/
- Lumberjack Validation: https://github.com/Rareloop/lumberjack-validation
- Sessions: https://github.com/Rareloop/lumberjack-core/tree/ft-session
- Lumberjack Example Repo: https://github.com/Rareloop/lumberjack-example
- Laravel Responsable: https://laravel-news.com/laravel-5-5-responsable
Towards the end of 2015 Rareloop launched their WordPress starter theme Lumberjack, which built on open source tools such as Bedrock and Timber. We wanted to move Lumberjack forward inline with everything we have learnt over the years of using it - which meant completely re-writing it from the ground up. The new Lumberjack is now stable and ready for use!
This talk is aimed at anyone involved in working with WordPress, regardless of how technical you are. The beauty of Lumberjack is that you can use as much or as little as you like, so whether you’re new to web development or a seasoned software engineer there will be something here for you.
How can we harness AEM6 and Sling to integrate backed layers to the CMS and expose them as a unified framework. creation of these integrations is vital for a coherent, personalize-able and track-able sites.
Akka is using the Actors together with STM to create a unified runtime and programming model for scaling both UP (multi-core) and OUT (grid/cloud). Akka provides location transparency by abstracting away both these tangents of scalability by turning them into an ops task. This gives the Akka runtime freedom to do adaptive automatic load-balancing, cluster rebalancing, replication & partitioning
Synthetic Models are not a new concept – but the concept is rarely used when developing in AEM/Sling/JCR.
They
Define domain objects where the domain is not exclusive to the content repository
Their property collection is defined against the data from each data source
Must be orchestrated by Sling’s resource resolution mechanism
Leverage the Presentation Model design pattern
Name is inspired by the SyntheticResource class
This definition came out of several past experiences where data from external sources was required to be brought into AEM and exposed to the presentation layer as if it was content.
Also through research on the problem I cam upon the SyntheticResource class. Think of it as the lesser-known cousin of Resource. It is often used to define resource objects that don’t exist in the JCR content tree or resources that are created at run-time
Building Reactive Systems with Akka (in Java 8 or Scala)Jonas Bonér
Learn how to build Reactive Systems with Akka. Examples in both Java 8 and Scala.
Abstract:
The demands and expectations for applications have changed dramatically in recent years. Applications today are deployed on a wide range of infrastructure; from mobile devices up to thousands of nodes running in the cloud—all powered by multi-core processors. They need to be rich and collaborative, have a real-time feel with millisecond response time and should never stop running. Additionally, modern applications are a mashup of external services that need to be consumed and composed to provide the features at hand. We are seeing a new type of applications emerging to address these new challenges—these are being called Reactive Applications.
In this talk we will introduce you to Akka and discuss how it can help you deliver on the four key traits of Reactive; Responsive, Resilient, Elastic and Message-Driven. We will start with the basics of Akka and work our way towards some of its more advanced modules such as Akka Cluster and Akka Persistence—all driven through code and practical examples.
Lessons learned from years of maintaining/extending/improving an in house CMS. Hopefully these will present things to avoid and things to try that will save others some pain.
This presentation explains what Computer Science actually entails. It covers ways to describe code performance using Big-Oh notation comparing different post meta and taxonomy queries and it discusses concurrency as it applies to WordPress, specifically data races and how they can occur while counting post views.
A deep dive into the inner workings of ClojureScript's analysis,
88 compilation, and runtime phases. The talk focused specifically on
89 the way that traditional JavaScript abstractions thwart code-size
90 and efficiency and how ClojureScript avoids such pitfalls. Finally,
91 I told a couple "war stories" about some of the specific challenges
92 met by the Clojure/core team during the development of the compiler
93 and runtime.
Supercharging WordPress Development in 2018Adam Tomat
Slide links:
- PHP-FIG: https://www.php-fig.org/psr
- Timber: https://www.upstatement.com/timber/
- Bedrock: https://roots.io/bedrock/
- Lumberjack: https://github.com/Rareloop/lumberjack
- Lumberjack Core: https://github.com/Rareloop/lumberjack-core
- Collections: https://laravel.com/docs/5.6/collections
- PHP-DI: http://php-di.org/
- Lumberjack Validation: https://github.com/Rareloop/lumberjack-validation
- Sessions: https://github.com/Rareloop/lumberjack-core/tree/ft-session
- Lumberjack Example Repo: https://github.com/Rareloop/lumberjack-example
- Laravel Responsable: https://laravel-news.com/laravel-5-5-responsable
Towards the end of 2015 Rareloop launched their WordPress starter theme Lumberjack, which built on open source tools such as Bedrock and Timber. We wanted to move Lumberjack forward inline with everything we have learnt over the years of using it - which meant completely re-writing it from the ground up. The new Lumberjack is now stable and ready for use!
This talk is aimed at anyone involved in working with WordPress, regardless of how technical you are. The beauty of Lumberjack is that you can use as much or as little as you like, so whether you’re new to web development or a seasoned software engineer there will be something here for you.
Rod Anderson
For the small business support person being able to provide PostgreSQL hosting for a small set of specific applications without having to build and support several Pg installations is necessary. By building a multi-tenant Pg cluster with one tenant per database and each application in it's own schema maintenance and support is much simpler. The issues that present themselves are how to provide and control dba and user access to the database and get the applications into their own schema. With this comes need to make logging in to the database (pg_hba.conf) as non-complex as possible.
MariaDB Server Compatibility with MySQLColin Charles
At the MariaDB Server Developer's meeting in Amsterdam, Oct 8 2016. This was the deck to talk about what MariaDB Server 10.1/10.2 might be missing from MySQL versions up to 5.7. The focus is on compatibility of MariaDB Server with MySQL.
CouchDB for Web Applications - Erlang Factory London 2009Jason Davies
CouchDB is built "of the Web" and it's very exciting to convert the immense
power that CouchDB provides into a usable, real-world Web application. In this
talk I cover case studies of real-world applications that use CouchDB,
including some that can be served from CouchDB itself, and how CouchDB can
shape your Web applications to be highly scalable and flexible by embracing
HTTP philosophies, JavaScript and schemaless documents.
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami
dotNet Miami - June 21, 2012: Presented by Richie Rump: Traditionally, Entity Framework has used a designer and XML files to define the conceptual and storage models. Now with Entity Framework Code First we can ditch the XML files and define the data model directly in code. This session will give an overview of all of the awesomeness that is Code First including Data Annotations, Fluent API, DbContext and the new Migrations feature. Be prepared for a fast moving and interactive session filled with great information on how to access your data.
Presentation at the Percona-Live event in San Francisco from Tamar Bercovici and me about the big scaling project of the MySQL database we did at Box in 2012.
Meetup developing building and_deploying databases with SSDTSolidify
Från Swedish Microsoft ALM DevOps Meetup 3, https://www.meetup.com/swedish-ms-alm-devops/events/236531424/
På denna träff kommer vi gräva oss ned i build & deployment och inleder med en presentation om hur man kan hantera databasuppdateringar som en del av deploymentflödet.
Slides from our CodeMash 2013 Precompiler session, "Web Development with Python and Django", including a breezy introduction to the Python programming language and the Django web framework. The example code repository is available at https://github.com/finiteloopsoftware/django-precompiler/
The web has changed! Users spend more time on mobile than on desktops and they expect to have an amazing user experience on both platforms. APIs are the heart of the new web as the central point of access data, encapsulating logic and providing the same data and same features for desktops and mobiles.
In this talk, I will show you how in only 45 minutes we can create full REST API, with documentation and admin application build with React.
"Functional Hostnames and Why they are Bad" by Andrew Fong and Gary Josack of Dropbox at Puppet Camp SF 2013. Find a Puppet Camp near you and learn more about configuration management: puppetlabs.com/community/puppet-camp/
Sharpen existing tools or get a new toolbox? Contemporary cluster initiatives...Orkestra
UIIN Conference, Madrid, 27-29 May 2024
James Wilson, Orkestra and Deusto Business School
Emily Wise, Lund University
Madeline Smith, The Glasgow School of Art
0x01 - Newton's Third Law: Static vs. Dynamic AbusersOWASP Beja
f you offer a service on the web, odds are that someone will abuse it. Be it an API, a SaaS, a PaaS, or even a static website, someone somewhere will try to figure out a way to use it to their own needs. In this talk we'll compare measures that are effective against static attackers and how to battle a dynamic attacker who adapts to your counter-measures.
About the Speaker
===============
Diogo Sousa, Engineering Manager @ Canonical
An opinionated individual with an interest in cryptography and its intersection with secure software development.
Acorn Recovery: Restore IT infra within minutesIP ServerOne
Introducing Acorn Recovery as a Service, a simple, fast, and secure managed disaster recovery (DRaaS) by IP ServerOne. A DR solution that helps restore your IT infra within minutes.
This presentation, created by Syed Faiz ul Hassan, explores the profound influence of media on public perception and behavior. It delves into the evolution of media from oral traditions to modern digital and social media platforms. Key topics include the role of media in information propagation, socialization, crisis awareness, globalization, and education. The presentation also examines media influence through agenda setting, propaganda, and manipulative techniques used by advertisers and marketers. Furthermore, it highlights the impact of surveillance enabled by media technologies on personal behavior and preferences. Through this comprehensive overview, the presentation aims to shed light on how media shapes collective consciousness and public opinion.
Have you ever wondered how search works while visiting an e-commerce site, internal website, or searching through other types of online resources? Look no further than this informative session on the ways that taxonomies help end-users navigate the internet! Hear from taxonomists and other information professionals who have first-hand experience creating and working with taxonomies that aid in navigation, search, and discovery across a range of disciplines.
This presentation by Morris Kleiner (University of Minnesota), was made during the discussion “Competition and Regulation in Professions and Occupations” held at the Working Party No. 2 on Competition and Regulation on 10 June 2024. More papers and presentations on the topic can be found out at oe.cd/crps.
This presentation was uploaded with the author’s consent.
Competition and Regulation in Professional Services – KLEINER – June 2024 OEC...
Modeling Tricks My Relational Database Never Taught Me
1. Modeling Tricks My Relational
Database Never Taught Me
David Boike
@DavidBoike
make-awesome.com
2. About Me
• Principal Consultant, ILM Professional Services
• NServiceBus Champion
• Author of Learning NServiceBus
• Husband, father, geek,
amateur beer brewer
• @DavidBoike
• www.make-awesome.com
5. SQL Server
• SQL first appeared – 1974
– Hard drive price: $185/MB, $189,000/GB
• Microsoft SQL Server 1.0 – 1989
– Hard drive price: $7.48/MB, $7,659/GB
• Current Version: SQL 2012
– November 2013: 0.004¢/MB, 4.096¢/GB
http://www.jcmit.com/diskprice.htm
19. Inheritance: Table per Class
Ale
BeerId
AleProp1
AleProp2
Beer
BeerId
Type
Name
ABV
IBU
Lager
BeerId
LagerProp1
LagerProp2
Stout
BeerId
StoutProp1
StoutProp2
23. Raven Inheritance
public class BeerListModel
{
public string Id { get; set; }
public List<BeerModel> Beers
{ get; set; }
public BeerListModel()
{
Beers = new List<BeerModel>();
}
}
public abstract class BeerModel
{
public string Name { get; set; }
public decimal ABV { get; set; }
public int IBU { get; set; }
}
public class AleModel : BeerModel
{
public string AleProp1 { get; set; }
public string AleProp2 { get; set; }
}
public class LagerModel : BeerModel
{
public string LagerProp1 { get; set; }
public string LagerProp2 { get; set; }
}
public class StoutModel : BeerModel
{
public string StoutProp1 { get; set; }
public string StoutProp2 { get; set; }
}
29. Raven Hierarchy #1
public class CategoryTree
{
// Sites/42/Categories
public string Id { get; set; }
public List<Category> RootCategories { get; set; }
public CategoryTree()
{
RootCategories = new List<Category>();
}
}
30. Raven Hierarchy #1
public class Category
{
public string CategoryId { get; set; }
public string Name { get; set; }
// Other Stuff
public List<Category> ChildCategories { get; set; }
public Category()
{
ChildCategories = new List<Category>();
}
}
32. Raven Hierarchy #2
public class Category
{
public string Id { get; set; }
public string Name { get; set; }
// Other Stuff
}
public class CategoryTree
{
public string Id { get; set; }
public List<CategoryRef> RootCategories { get; set; }
}
public class CategoryRef
{
public string CategoryId { get; set; }
public List<CategoryRef> ChildCategories { get; set; }
}
// Don't forget default constructors!
34. Loading Hierarchy
• Method 1
– One document, just load it
• Method 2
– Multiple Documents
– Normally to load within collections
• .Include("RootCategories,CategoryId")
• Does not work recursively
• Works fine for one level
35. Loading Hierarchy
var tree = RavenSession
.Load<CategoryTree>("Sites/42/CategoryTree");
// Recursively build list of ids needed
string[] ids = RecurseOnYourOwnTime(tree); // ;-)
var cats = RavenSession
.Load<Category>(ids)
.ToDictionary(doc => doc.Id);
36. Hierarchy: Lessons
• Model by Units of Change and Transactional
Boundaries
– Guided our choice of hierarchy implementation
– Think about actors in your use cases
• Always initialize collections and child objects
– Nobody likes a NullReferenceException
• We can have global “singleton” documents for
configuration
– Site/Configuration, Site/Categories, etc.
– Great candidates for Aggressive Caching
40. Copy a Post
• 3 tables involved
– wp_posts
– wp_postmeta (17 types)
– wp_term_relationships
• More if we want to copy comments
– wp_comments
– wp_commentmeta
41. Copy a Post
• Fairly simple example
– New row in Posts
• Store new PostId
– New rows in PostMeta w/ PostId
– New rows in TermRelationships w/ PostId
• What if we had to copy a table related to
TermRelationships?
• What if an object graph spans dozens of tables?
• What if PostMeta contains hidden ids linking to other
tables?
• P.S. Revisions are stored as additional
records in Posts!
42. Raven Post Model Example
public class WordPressPost
{
public string Id { get; set; }
public string AuthorId { get; set; }
public DateTimeOffset PostDate { get; set; }
public string Contents { get; set; }
public string Title { get; set; }
public string Excerpt { get; set; }
public PostStatus Status { get; set; }
// etc.
public List<string> Categories { get; set; }
public List<string> Tags { get; set; }
public List<string> Series { get; set; }
public List<string> RelatedPostIds { get; set; }
public List<PostLink> Links { get; set; }
public List<PostMedia> Media { get; set; }
// Comments?...
}
43. Options for Comments
1. Add to WordPressPost :
public List<PostComment> Comments { get; set; }
2. Document per comment
3. Separate document for comments
• WordPressPosts/1
• WordPressPosts/1/comments
4. Capped documents
• WordPressPosts/1
• WordPressPosts/1/comments/1
• WordPressPosts/1/comments/2
• WordPressPosts/1/comments/3
45. How to duplicate?
// Global.asax / App_Start config
Mapper.Initialize(cfg =>
{
cfg.CreateMap<BlogPost, BlogPost>()
.ForMember(p => p.Id,
opts => opts.Ignore());
});
Can also decorate model’s Id property with
IgnoreMapAttribute but this leaks a dependency to
AutoMapper in your models.
46. How to duplicate?
BlogPost post =
RavenSession.Load<BlogPost>("BlogPosts/1");
BlogPost dupe = Mapper.Map<BlogPost>(post);
// dupe.Id == null
RavenSession.Store(dupe);
// dupe.Id == "BlogPosts/2"
47. Why duplicate?
• User Duplicate function (duh)
• Auditing/History
– Posts/1/History/yyyyMMddHHmmss
– Consider Versioning bundle for auditing EVERY
document modification
• Preview
– Posts/1/Preview/ecbe7b49c3de4c8394880bdd81eeae97
• Use Expiration Bundle
• Complex Edit/Publish/Cancel
– Posts/1/Edit/davidboike
• Use Expiration Bundle
48. Duplication: Lessons
• Thinking about duplication can help to identify
units of change, but can’t get us all the way
• Make use of semantic IDs
• Duplicating data enables many advanced
scenarios
• Think about possible document growth
• Break down large documents within one unit
of change into slimmer documents
50. NServiceBus/Sagas 101
• NServiceBus
– Framework for creating distributed systems
– Transactional message handlers w/ auto-retry
– Publish/Subscribe
• NServiceBus Sagas
– Correlated message handlers with shared state
– Transactional state stored between messages
– Similar in concept to ASP.NET Session State
51. Saga Storage Interface
public interface ISagaPersister
{
T Get<T>(Guid sagaId);
T Get<T>(string property, object value);
void Save(IContainSagaData saga);
void Update(IContainSagaData saga);
void Complete(IContainSagaData saga);
}
public interface IContainSagaData
{
Guid Id { get; set; }
string Originator { get; set; }
string OriginalMessageId { get; set; }
}
52. Saga Storage History
• NServiceBus 2.0
– SQL Storage via Fluent NHibernate
• It sucked
– Built my own based on XmlSerializer
• That also sucked, just not as much
• NServiceBus 3.0
– RavenDB Saga Persister became default
– Villagers rejoiced!
53. Fluent NHibernate
public class MySagaData : IContainSagaData
{
public virtual int MessagesReceived { get; set; }
// Don't touch! NServiceBus uses these internally!
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
}
MySagaData
Id
Originator
OriginalMessageId
MessagesReceived
54. Fluent NHibernate
public class MySagaData : IContainSagaData
{
public virtual int MessagesReceived { get; set; }
// Don't touch! NServiceBus uses these internally!
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
}
MySagaData
Id
Originator
OriginalMessageId
MessagesReceived
55. Fluent NHibernate
public class MySagaData : BaseSagaData
{
public virtual int MessagesReceived { get; set; }
}
public abstract class BaseSagaData : IContainSagaData
{
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
}
MySagaData
Id
MessagesReceived
BaseSagaData
Id
Originator
OriginalMessageId
56. Fluent NHibernate
public class MySagaData : IContainSagaData
{
public virtual List<string> MessageTypesReceived { get; set; }
// Don't touch!
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
}
57. Fluent NHibernate
public class MySagaData : IContainSagaData
{
public virtual List<string> MessageTypesReceived { get; set; }
// Don't touch!
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
}
58. Fluent NHibernate
public class MySagaData : IContainSagaData
{
public virtual List<ReceivedMessage> MessageTypesReceived { get; set; }
// Don't touch!
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
}
public class ReceivedMessage
{
public virtual Guid Id { get; set; }
public virtual string MessageTypeReceived { get; set; }
}
MySagaData
Id
Originator
OriginalMessageId
ReceivedMessage
Id
MySagaDataId
MessageTypeReceived
59. Raven Saga Persistence
public class MySagaData : ContainSagaData
{
public List<string> MessageTypesReceived { get; set; }
}
-OR-
public class MySagaData : ContainSagaData
{
public HashSet<Type> MessageTypesReceived { get; set; }
}
60. Back to ISagaPersister
public interface ISagaPersister
{
T Get<T>(Guid sagaId);
T Get<T>(string property, object value);
void Save(IContainSagaData saga);
void Update(IContainSagaData saga);
void Complete(IContainSagaData saga);
}
Need to be able to load a saga by any identifiable
property that matches on the incoming message
and saga data.
61. More Real-Life Saga
Shipping Saga:
• Waits for OrderAccepted + OrderBilled events
• Publishes OrderShipped event
public class ShippingData : ContainSagaData
{
[Unique]
public long OrderId { get; set; }
public List<string> MessageTypesReceived { get; set; }
}
UniqueAttribute
• NHibernate persister would create a unique index on the column
• RavenDB indexes are asynchronous and NOT consistent
– Consistency only guaranteed on Store/Load by ID
63. OpenID/OAuth
• Login with multiple 3rd-party identities also requires
pointer document modeling
• OpenID identity URLs make for horrible document IDs
– Use the SHA1 hash of the login provider and login
identifier in the document ID instead.
• Easy way with MVC5
– RavenDB.AspNet.Identity NuGet package
– https://github.com/ILMServices/RavenDB.AspNet.Identity
– At least look at the source and make fun of the author
(That’s me)
65. NServiceBus: Lessons
• Document databases are ideal for storing
random objects with little friction
• Unique constraints must be treated specially
to ensure consistency
– Custom pointer documents
– Unique Constraints bundle for more generic
functionality (though I prefer not to overuse it)
• Use RavenDB.AspNet.Identity for OpenID
– Better yet send me a pull request!
67. Final Thoughts
Above all else, think about how and why data
changes.
– Units of Change
– Transactional Boundaries
– Everything else is window dressing
68. Final Thoughts
Like relational modeling, document modeling is
a skill that is acquired through experience
– Model things like you would in the real world
– Don’t be afraid of trying and failing
– Create a /FakeData/Create action in your site to
bootstrap your database to make this easy
– Especially in the early stages of an application,
experiment often and regenerate when needed