Asynchronous, High-Performance Login for Web Farms
When looking deeper into this workflow, you realize that it could be implemented as two separate message handlers, and have the email address take the place of the workflow ID. The problem with this alternate, better performing solution has to do with security. By removing the dependence on the workflow ID, you've in essence stated that you're willing to receive a UserValidatedMessage without having previously received the RegisterUserMessage.
Because the processing of the UserValidatedMessage is relatively expensive—writing to the DB and publishing messages to all web servers, a malicious user could perform a denial of service (DOS) attack without that many messages, thus flying under the radar of many detection systems. Spoofing a guid that would result in a valid workflow instance is much more difficult. Also, because workflow instances would probably be stored in some in-memory, replicated data grid, the relative cost of a lookup would be quite small—small enough to avoid a DOS until a detection system picked it up.
Improved Bandwidth and Latency
The important thing to remember in this solution is doing pub/sub. nServiceBus merely provides a simple API for designing the system around pub/sub. And, publishing is where you get the serious scalability. As you get more users, you'll obviously need to get more web servers. The thing is that you probably won't need more database servers just to handle logins. In this case, you also get lower latency per request becaise all work needed to be done can be done locally on the server that received the request.
ETags Make It Even Better
For the more advanced crowd, I'll wrap it up with the ETags. Because web servers do go down, and the cache will be cleared, what you can do is to write that cache to disk (probably in a background thread), and "tag" it with something that the server gave you along with the last UsernameInUseMessage you received. That way, when the web server comes back up, it can send that ETag along with its GetAllUsernamesMessage so that the app server will only send the changes that occurred since. This can be done REST style as well, using HTTP GET with an additional "If-Modified-Since" header. All this drives down network usage even more at the insignificant cost of some disk space on the web servers.
Even if you don't have anything more than a single physical server today, and it acts as your web server and database server, this solution won't slow things down. If anything, it'll speed it up. Regardless, you're much better prepared to scale out than before—no need to rip and replace your entire architecture just as you get 8 million Facebook users banging down your front door.
- http://www.nServiceBus.com: nServiceBus is an open source communications framework that makes building enterprise .NET systems easier. By providing scalability critical features such as publish/subscribe support, integrated long-running transactions, and deep extensibility, nServiceBus provides a solid foundation for any distributed system.
- Podcast on Autonomous Servers and Publish/Subscribe: This podcast addresses questions about autonomous services, publish/subscribe communication, exceptions, data duplication, reuse, and governance.
About the Author
Udi Dahan is The Software Simplist, a Microsoft Solutions Architect MVP, recognized .NET expert, and a member of both the Microsoft Architects and Technologists Councils. Udi provides clients all over the world with training, mentoring, and high-end architecture consulting services, specializing in Service-Oriented, scalable, and secure .NET architecture design.
He is a member of the International Speakers Bureau of INETA, an associate member of the International Association of Software Architects (IASA), a Dr. Dobb's sponsored expert on Web Services, SOA, & XML, an editor for InfoQ, a frequent conference presenter, and a regularly published author.
Udi can be contacted via his blog www.UdiDahan.com.
Page 3 of 3