1

I'm working on a simple game using SignalR 2 and MVC 5. I need to track number of "deaths" and "kills" for each user. These stats need to be read/write from multiple game instances (user can have multiple concurrent sessions) across multiple servers.

Is adding fields to ApplicationUser : IdentityUser a reasonable solution? I'm planning on using the built-in authentication system because I like how easy it is to support Facebook and other OAuth providers.

How should I update these stats in an optimized manor that reduces multi-user/threads/server issues and is highly scalable? The stats themselves are simple, and probably only update once every few seconds per user, but I'd like a design that can support millions of users across multiple servers.

For example, I know I could add this code inside an MVC controller to update the stats:

    var um = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
    var user = um.FindById(User.Identity.GetUserId());
    user.Deaths++;
    um.Update(user);

However, that doesn't seem very safe/transactional. If another process/connection/server is updating that user at the same time, bad things are likely.

In a pure SQL design I'd probably have a stored procedure that runs in a SQL transaction to get current counter, and increment it. Not sure how to translate that to a good SignalR design that takes advantage of all that the various API layers have to offer (OWIN, MVC, ASP.NET, etc). Ideally something I can easily add Redis to down the road, if direct SQL access becomes an issue.

eselk
  • 6,764
  • 7
  • 60
  • 93
  • I agree, that in a multi-threaded context having the death/kill counter updated in the database could lead to unsafe transactions. I would try pushing items to a common queue, with a single threaded processing class that de-queues them and performs the appropriate action. – AWinkle Oct 11 '15 at 20:37
  • 1
    Also - thank you for preemptively supporting multi-instance gamers. We appreciate it. – AWinkle Oct 11 '15 at 20:38
  • Thank you for the ideas. I'm hoping something as common as I think this is has a simple existing solution, but if not, the queue idea sounds good and I'll probably just implement Redis at the same time, if I have to go to that trouble anyway. – eselk Oct 11 '15 at 23:26
  • If the class updating SQL is guaranteed to be a single-instance, you could use `lock`. – AWinkle Oct 12 '15 at 14:06

0 Answers0