Sunday, May 24, 2015

Using Redis Client Code Snippets with ServiceStack

Code snippets in an MVC application:

using (IRedisClient redisClient = new RedisClient())
{      
      var userClient = new redisClient.GetTypedClient<User>();      
      var user = new User {                            
                                        Name = "Clint",                           
                                        Id = userClient.GetNextSequence()                     
      };               
      userClient.Store(user); // Save new User
}

On the redis-cli.exe command line, type monitor to see what's happening when you run the app.


MVC View to submit UserId from a dropdown selection to another Controller's action:

Select User:
@using (Html.BeginForm("Index", "Tracker", FormMethod.Post))
{     
    @DropDownList("userId", null, string.empty, new {@onchange = "form.submit();"});
}
@Html.ActionLink("Create New User", "NewUser", "Users");

Now with Redis, for Updates we don't really do an UPDATE like SQL. Instead we fetch the User, edit the data and RE-SAVE the User object.

And here's how you would associate a list of data with an User key-value pair. Create a set (list) which stores the UserId as a key value and a list of data (say integer values) for each Userid.

using (IRedisClient redisClient = new RedisClient())

      long userId = 213;
      int amount = 100;
    
      var userClient = new redisClient.GetTypedClient<User>();
      var user = userClient.GetById(userId);
  
      var historyClient = redisClient.GetTypedClient<int>();
      var historyList = historyClient.Lists["urn:history:" + userId];

      user.Total += amount;       
      userClient.Store(user); // Update User

      historyList.Prepend(amount); // always push to first item in the list
      historyList.Trim(0, 4); //restrict items in list to always 5 items

      /* Add to a sorted set that stores Users with key=name and value=total
         The beauty of Redis is it will not cause dups here and just updates the Total
         and maintains this sorted list! No code to write to check for dups etc.
     */
      redisClient.AddItemToSortedSet("urn:leaderboard", user.Name, user.Total);

      ViewBag.HistoryItems = historyList.GetAll();
}


//And to retrieve the leaderboard set, just call a method on the Redis client:
var leaderboard = redisClient.GetAllWithScoresFromSortedSet("urn:leaderboard");

Note; To avoid duplicates getting into the sorted set if we change the name of the User, make sure to remove the User from the sorted set whenever we "update", and then adding the User back again to the Sorted Set when we re-save the User. To remove the User from the sorted set, call redisClient.RemoveItemfromSortedSet("urn:leaderboard", user.Name).

And there you go! As simple as that.

TODO:

  • Add the ability to delete Users (slightly complicated as you need to keep track of where all your User data are)
  • Moving the history data to the User object rather than having it in its own list of integers
  • Store the User data in a hash. Is there any benefit to that?


Reference: Pluralsight training on Building NoSQL With Redis by John Sonmez
http://www.pluralsight.com/courses/building-nosql-apps-redis



No comments:

Post a Comment