HBase HTablePool: correct usage - connection-pooling

What is the correct usage pattern of HTablePool? I mean, assume that I have my DAO which is initialised with an instance of HTablePool. This DAO is a member instance of a Stateless Session Bean so it is reused between invocations.
What is the correct usage beween the following?
private HTableInterface aTable;
public XYZDAO(final HTablePool pool)
{
this.aTable = pool.getTable(...);
}
public void doSomething(...)
{
aTable.get(...)
}
or HTablePool should be used like a Datasource and therefore is more appropriate a usage like this
private HTablePool datasource;
public XYZDAO(final HTablePool pool)
{
this.datasource = pool;
}
public void doSomething(...)
{
HTableInterface aTable = datasource.getTable(...);
aTable.get(...);
aTable.close();
}

The second approach is the best, you should use HTablePool like it was a Datasource since the HTable class is not thread safe. A call to the close method of HTableInterface will automatically return the table to the pool.
Note that there is HConnection interface that replaces the deprecated HTablePool in newer HBase versions.

Yes the second approach is better but rather than closing the Table you should put it back in to the pool:
public void createUser(String username, String firstName, String lastName, String email, String password, String roles) throws IOException {
HTable table = rm.getTable(UserTable.NAME);
Put put = new Put(Bytes.toBytes(username)); put.add(UserTable.DATA_FAMILY, UserTable.FIRSTNAME,
Bytes.toBytes(firstName));
put.add(UserTable.DATA_FAMILY, UserTable.LASTNAME, Bytes.toBytes(lastName));
put.add(UserTable.DATA_FAMILY, UserTable.EMAIL, Bytes.toBytes(email));
put.add(UserTable.DATA_FAMILY, UserTable.CREDENTIALS,
Bytes.toBytes(password));
put.add(UserTable.DATA_FAMILY, UserTable.ROLES, Bytes.toBytes(roles)); table.put(put);
table.flushCommits();
rm.putTable(table);
}
Example Code taken from the Book "HBase: The Definitive Guide".
EDIT: I'm wrong doc after v0.92 states:
This method is not needed anymore, clients should call HTableInterface.close() rather than returning the tables to the pool Once you are done with it, close your instance of HTableInterface by calling HTableInterface.close() rather than returning the tables to the pool with (deprecated) putTable(HTableInterface).

Related

How to use a Session provider in a DI project

I am developing a web application in ASP.NET MVC5.
Like all basic web applications it also has a login page where a user can authenticate himself. Once authenticated I want to store a couple of user-related items in the Session so I don't have to query the database every time to reconstruct the authenticated user.
After having read Mark Seemann's book about Dependency Injection I want to loosely couple all my layers and make sure that everything can easily be replaced.
At the moment my SessionProvider is by default using the Session object, but maybe in the future this could change to another type of storage mechanism.
The approach I have taken is by using Ambient Context which he explained with the TimeProvider example, but I am wondering if this is the right approach for this functionality and if it is thread safe (also for unit testing).
Is my solution proper or how would you implement such a mechanism? This has been in my head for days now so who can help me define the best solution?
Thanks!
public abstract class SessionProvider
{
private static SessionProvider _current;
static SessionProvider()
{
_current = new DefaultSessionProvider();
}
public static SessionProvider Current
{
get { return _current; }
set
{
if (value == null)
{
throw new ArgumentNullException();
}
_current = value;
}
}
public abstract string UserName { get; set; }
}
My local default:
public class DefaultSessionProvider : SessionProvider
{
public override string UserName
{
get { return (string) HttpContext.Current.Session["username"]; }
set { HttpContext.Current.Session["username"] = value; }
}
}
So I have access in my entire solution to my SessionProvider, whether this is a real session object or a database-driven storage mechanism...
SessionProvider.Current.UserName = "myUserName";
Once authenticated I want to store a couple of user-related items in
the Session so I don't have to query the database every time to
reconstruct the authenticated user.
Well, it looks like you're working on some sort of caching mechanism. It doesn't really matter if it's in a Session or in Redis cache, or any other type of cache. And this cache is key-value storage. I would create cache interface, something like that:
interface ICache
{
object this[string key] {get; set;}
}
And create concrete classes. SessionCache in your case:
public SessionCache : ICache
{
private IHttpSessionState _session;
public SessionCache(IHttpSessionState session)
{
_session = session;
}
// ICache implementation goes here...
}
So you'll narrow down the problem to dependency-inject Session object to concrete class (SessionCache). With Ninject you can do something like:
.WithConstructorArgument("session",ninjectContext=>HttpContext.Session);
And after that you can finally make your controllers dependent on ICache.
In your unit tests project you can create another ICache concrete class, something like DummyCache with in-memory cache. So you can test your controllers without sticking to Session object.

Async method hanging in asp.net

Environment: ASP.NET MVC 5, SQL Server
Here is my method that returns current user's profile from the database:
public static ProfileModel getCurrentProfile(HttpContextBase ctx) {
User user = AccountController.getUser(ctx);
Task<ProfileModel> model = ProfileModel.getValue(user.UserID);
model.Wait();
return model.Result;
}
Upon execution, model.Wait() just hangs up.
I have read several articles about deadlocks and using ConfigAwait(false) for such situations. However, there would be lot of places I would need to call this method. I am thinking if I fix it the right way, I may be able to avoid ConfigAwait() calls altogether.
Here is how I am using the method in my index.cshtml file:
Members.Models.ProfileModel userModel = HomeController.getCurrentProfile(Context);
Html.RenderPartial("_PartialPublicProfile", userModel);
File _PartialPublicProfile requires ProfileModel instance to be passed in. Is it possible to pass in Task<ProfileModel> instance as a parameter?
Or, is there a better way to solve the problem? Regards.
You're essentially trying to run an async task synchronously. You have to be very careful about how you do that or else your application can and will hang.
In Entity Framework 6, there are now sync and async data access methods, but importantly, the sync versions call the async versions synchronously. To pull this off the EF team uses the following internal helper class. I would recommend implementing this as your own helper class, and then using it in all scenarios where you need to call an asynchronous method synchronously:
public static class AsyncHelper
{
private static readonly TaskFactory _myTaskFactory = new
TaskFactory(CancellationToken.None,
TaskCreationOptions.None,
TaskContinuationOptions.None,
TaskScheduler.Default);
public static TResult RunSync<TResult>(Func<Task<TResult>> func)
{
return AsyncHelper._myTaskFactory
.StartNew<Task<TResult>>(func)
.Unwrap<TResult>()
.GetAwaiter()
.GetResult();
}
public static void RunSync(Func<Task> func)
{
AsyncHelper._myTaskFactory
.StartNew<Task>(func)
.Unwrap()
.GetAwaiter()
.GetResult();
}
}
So, in your particular scenario here, you code would change to:
public static ProfileModel getCurrentProfile(HttpContextBase ctx){
User user = AccountController.getUser(ctx);
var model = AsyncHelper.RunSync<ProfileModel>(() => ProfileModel.getValue(user.UserID));
return model;
}

Injecting ParseUser object to Controller

I'm trying to use parse's .net client in an mvc web application.
and couldn't find a proper way to inject ParseObject, ParseUser and ParseUser.CurrentUser
what is the nice way of injecting static objects?
web app has a Forms authentication setup.
and ioc container register components or services LifestylePerWebRequest()
my problem occured when I want to update the user object,
only if the ParseUser.CurrentUser logged in we can update. (https://parse.com/docs/dotnet_guide#users-security)
but this is a static object and I get the latest signed in user...
now I'm thinking to create a user2 table in parse and keep all profile data in there...
Is there a better way to go?
public async Task<bool> UpdateUser(string id, string name, string surname)
{
//var user = ParseUser.CurrentUser;
var user = await ParseUser.Query.GetAsync(id);
if (user == null) return await Task.FromResult(false);
user.Name = name;
user.Surname = surname;
await user.SaveAsync();
return await Task.FromResult(true);
}
what is the nice way of injecting static objects?
You hide them behind an application-defined abstraction. You define a narrow interface that describes the functionality that your application needs (and ideally without the interface leaking the external framework). For instance:
public interface IUserRepository
{
// Throws an exception on failure.
void UpdateUser(string id, string name, string surname);
}
Now you can hide the static class behind an implementation of IUserRepository:
public class ParseUserRepository : IUserRepository
{
public void UpdateUser(string id, string name, string surname)
{
// call the static Parse functionality.
}
}

Persist data between different controllers from a base page

I am not sure I am asking the right question here.
I have a shared page (master page) that calls a couple of partial pages for side menu, header, footer etc.. and all my controllers inherit a BaseController.
Now, depending on the user login status, I need to show different data in all those partial pages and I thought where is the best place to check whether a user is logged in or not - BaseController.
And therein lies my problem. I need to contact one of my web services to see if a user is logged in and get some relevant data if he is. I only need to do this once, and since all controllers inherit from BaseController, each of those partial page calls results in the web service call.
Obviously, I cannot just stick a private bool variable isUserAuthenticated and check for flag, as, each controller will have a new instance of the base controller.
In traditional asp.net projects, I would put this stuff in HttpContext.Current.Items[] and use re-use it but I cannot (somehow) access that in MVC.
I cannot just not inherit from basepage on partial pages as they can also be called independently and I need to know the user login status then too.
What is the best way to call a function just once, or, rather, store a bool value for the duration of one call only? - accessible between controlers..
How do people do this?
thanks, sorry, I'm a newbie to mvc!
You can still use HttpContext.Items, but you'll need to access it via a HttpContextBase instance.
For backwards compatibility you can wrap an HttpContext in an HttpContextWrapper, like so
var context = new HttpContextWrapper(HttpContext.Current);
#iamserious's answer above suggests using a static property - which I strongly disagree with. Setting a static variable is application wide and would mean each and every user would be using the same variable - so all would have the same login data. You want to store it either per user in Session or per Request via HttpContext.Items.
I'd suggest doing something using like this approach, then no matter where you call ContextStash.GetInstance, you'll receive the same instance for the lifetime of the same request. You could also follow the same pattern and use HttpContext.Session instead of HttpContext.Items:
// could use this.HttpContext inside a controller,
// or this.Context inside a view,
// or simply HttpContext.Current
var stash = ContextStash.GetInstance(this.HttpContext);
if(!stash.IsSomething)
{
// do something to populate stash.IsSomething
}
// class
public class ContextStash
{
const string cacheKey = "ContextStash";
public ContextStash(HttpContextBase context)
{
// do something with context
}
// your shared properties
public bool IsSomething { get; set; }
public string Foo { get; set; }
public int Bar { get; set; }
// instance methods
public static ContextStash GetInstance()
{
return GetInstance(new HttpContextWrapper(HttpContext.Current));
}
public static ContextStash GetInstance(HttpContext context)
{
return GetInstance(new HttpContextWrapper( context ));
}
public static ContextStash GetInstance(HttpContextBase context)
{
ContextStash instance = context.Items[cacheKey] as ContextStash;
if(null == instance)
{
context.Items[cacheKey] = instance = new ContextStash(context);
}
return instance;
}
}
well, if you just want to one variable across several instances of BaseController, use the static keyword, like so:
public class BaseController : Controller
{
private static bool isUserAuthenticated;
}
Now, no matter how many instances of BaseController you have, they all will share a single isUserAuthenticated variable, you change value in one, you change it in all.
This is the very basic of most object oriented programming and you should really take some time out to go through the concepts of OOP, if you don't mind me saying.

Can I serialize an object if I didn't write the class used to instantiate that object?

I've a simple class
[Serializable]
public class MyClass
{
public String FirstName { get; set: }
public String LastName { get; set: }
//Bellow is what I would like to do
//But, it's not working
//I get an exception
ContactDataContext db = new ContactDataContext();
public void Save()
{
Contact contact = new Contact();
contact.FirstName = FirstName;
contact.LastName = LastName;
db.Contacts.InsertOnSubmit(contact);
db.SubmitChanges();
}
}
I wanted to attach a Save method to the class so that I could call it on each object. When I introduced the above statement which contains ContactDataContext, I got the following error "In assembly ... PublicKeyToken=null' is not marked as serializable"
It's clear that the DataContext class is generated by the framework (). I checked and did not see where that class was marked serialize.
What can I do to overcome that? What's the rule when I'm not the author of a class? Just go ahead and mark the DataContext class as serializable, and pretend that everything will work?
Thanks for helping
It might be worth taking a step back and seeing if what you want to achieve is really valid.
Generally, a serializable class is used for data transport between two layers. It is more likely to be a simple class that only holds data.
It seems a little out of place for it to hold the ability to persist to a database. It is not likely that both ends of the pipe actually have access to the database, and it seems very unlikely that they would both have the ability to persist data.
I wonder if it's worth factoring the save out to a repository. So have a repository class that will accept the data transfer object, construct the database object and save it.
This will simplify your code and completely avoid the problem you're having. It will also greatly enhance testability.
The problem is that the db field gets serialized, while clearly it doesn't need to be serialized (it's instantiated once the object is created).
Therefore, you should decorate it with the NonSerialized attribute:
[NonSerialized]
ContactDataContext db = new ContactDataContext();
[Update]
To make sure the db field is accesable after object initialization, you should use a lazy loading property and use this property instead of the field:
[NonSerialized]
ContactDataContext db = null;
[NonSerialized]
private ContactDataContext {
get {
if (db == null) {
db = new ContactDataContext();
}
return db;
}
set {
db = value;
}
}
public void Save()
{
Contact contact = new Contact();
contact.FirstName = FirstName;
contact.LastName = LastName;
Db.Contacts.InsertOnSubmit(contact);
Db.SubmitChanges();
}
[Update2]
You can serialize most objects, as long as it has a public parameterless constructor (or no constructor at all) and no properties/fields that cannot be serialized but require serializing. If the class itself is not marked as [Serializable], then you can do this yourself using a partial class. If the class has properties/fields that cannot be serialized, then you might achieve this by inheriting the class and overriding these properties/fields to decorate them as [NonSerialized].
You can create a surrogate that knows how to serialize the dodgy classes - see here for an example
I think you do need to decorate the base class, however, the DataContext auto generated classes are marked as partial. Have you tried doing something like:
[Serializable]
public partial class ContactDataContext
{
}
Not sure if it would work but its worth a try.

Resources