Retain array in memory on application restart - c++

I have a C++ backend server application. When our users login to the application, a SESSION Object (Complex C++ Object containing database connections, access rights, pointers etc) is created for each user. The Object is then maintained in an array. I am using a batch script to restart application in case of crash.
The issue is, in case the application crashes, the array of SESSIONS is destroyed. When the application starts again the array is empty. Hence the users are required to login again.
Is there a any method to retain the array of SESSIONS across application restarts?
I am using Qt 5.5 framework and the OS is Ubuntu Linux.
Code:
static QHash<QString,Session*> sessions
class Session {
bool logged_in;
QString aID;
QString sID;
QMap<QString,QMap>;
QMap<QString,QVariant> m_vars;
bool m_database;
int m_minutes;
QTimer* m_sessionTimer;
bool m_valid;
CustomClass* CustomClass;
CustomClass2* CustomClass;
QTimer* timer;
QList <CustomClass3*> objects;
}
CustomClass {
//15 getter-setter functions...
CustomClassInterface interface; //PIMPL
}
CustomClassInterface {
DatabaseClass database;
CustomUserClass userClass;
//...More 5-6 QList items
}
CustomClass2 {
//15 getter-setter functions...
CustomClass2Interface interface; //PIMPL
}
CustomClass2Interface {
DatabaseClass database;
CustomUserClass userClass;
//...More 5-6 QList items
}
...
The class is huge so I can't write the whole code here
Adding serialisation to all class would require to rewrite bunch of libraries. So, isn't there any other approach without implementing serialisation. Like mmap or something.

Can you save the sessions in a database/file when you create/update them? Whenever you start the server, restore them.

Hint: Separation of concerns
You can use a separate process to handle/store the credentials.

Related

Using Redis with uWebSockets C++ server

I currently have a C++ web sockets server using uWebSockets. I want to scale it horizontally using Redis. It means that I'll use this Redis client.
However, I'm facing a problem with the implementation of pub/sub channels. Indeed, since the Redis channel subscription needs its own event loop (according to this example), and obviously the same for the uWebSockets app (see this example), I end up with two event loops. And my problem is that I don't know how to manage running these two loops properly.
I tried running them on two different threads, which works if they are totally independent of each other. However, since I want to broadcast the upcoming Redis message to all web sockets client, I need the uWebSockets app instance (see this example) in the Redis thread to broadcast it:
Subscriber sub = redis->subscriber();
sub.on_message([](std::string channel, std::string msg){
app->publish("broadcast", msg, (uWS::OpCode)1);
});
Therefore the two event loops are not independant of each other and when I received a message from Redis, it takes about 5 seconds before it is handled by the uWebSockets app.
Does someone know how to properly set up this Redis pus/sub feature ? Thank you for your help.
I managed to solve my problem.
I found that calling app->publish(...) in my second thread was not thread-safe. Indeed, an interesting post showed me that in order to access the app from another thread, we have to use the method defer on the event loop. Therefore, the structure becomes:
...
uWS::SSLApp *app = nullptr;
uWS::Loop *loop = nullptr;
Redis *redis = nullptr;
...
void redisEventLoopThread(Subscriber *sub) {
sub->on_message([](string channel, string msg) {
loop->defer([msg]() {
app->publish(channel, msg, ...);
});
});
sub->subscribe("channel_name");
while (true) {
try {
sub->consume();
} catch (const Error &err) {...}
}
}
...
int main() {
app = new uWS::SSLApp();
loop = uWS::Loop::get();
redis = new Redis(...);
Subscriber sub = redis->subscriber();
thread redisThread(redisEventLoopThread, &sub);
app->ws<...>(...).listen(...).run();
...
}

Eclipse RAP Multi-client but single server thread

I understand how RAP creates scopes have a specific thread for each client and so on. I also understand how the application scope is unique among several clients, however I don't know how to access that specific scope in a single thread manner.
I would like to have a server side (with access to databases and stuff) that is a single execution to ensure it has a global knowledge of all transaction and that requests from clients are executed in sequence instead of parallel.
Currently I am accessing the application context as follows from the UI:
synchronized( MyServer.class ) {
ApplicationContext appContext = RWT.getApplicationContext();
MyServer myServer = (MyServer) appContext.getAttribute("myServer");
if (myServer == null){
myServer = new MyServer();
appContext.setAttribute("myServer", myServer);
}
myServer.doSomething(RWTUtils.getSessionID());
}
Even if I access myServer object there and trigger requests, the execution will still be running in the UI thread.
For now the only way to ensure the sequence is to use synchronized as follows on my server
public class MyServer {
String text = "";
public void doSomething(String string) {
try {
synchronized (this) {
System.out.println("doSomething - start :" + string);
text += "[" + string + "]";
System.out.println("text: " + (text));
Thread.sleep(10000);
System.out.println("text: " + (text));
System.out.println("doSomething - stop :" + string);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Is there a better way to not have to manage the thread synchronization myself?
Any help is welcome
EDIT:
To better explain myself, here is what I mean. Either I trust the database to handle multiple request properly and I have to handle also some other knowledge in a synchronized manner to share information between clients (example A) or I find a solution where another thread handles both (example B), the knowledge and the database. Of course, the problem here is that one client may block the others, but this is can be managed with background threads for long actions, most of them will be no problem. My initial question was, is there maybe already some specific thread of the application scope that does Example B or is Example A actually the way to go?
Conclusion (so far)
Basically, option A) is the way to go. For database access it will require connection pooling and for shared information it will require thoughtful synchronization of key objects. Main attention has to be done in the database design and the synchronization of objects to ensure that two clients cannot write incompatible data at the same time (e.g. write contradicting entries that make the result dependent of the write order).
First of all, the way that you create MyServer in the first snippet is not thread safe. You are likely to create more than one instance of MyServer.
You need to synchronize the creation of MyServer, like this for example:
synchronized( MyServer.class ) {
MyServer myServer = (MyServer) appContext.getAttribute("myServer");
if (myServer == null){
myServer = new MyServer();
appContext.setAttribute("myServer", myServer);
}
}
See also this post How to implement thread-safe lazy initialization? for other possible solutions.
Furthermore, your code is calling doSomething() on the client thread (i.e. the UI thread) which will cause each client to wait until pending requests of other clients are processed. The client UI will become unresponsive.
To solve this problem your code should call doSomething() (or any other long-running operation for that matter) from a background thread (see also
Threads in RAP)
When the background thread has finished, you should use Server Push to update the UI.

Invalid address specified to RtlValidateHeap in cross-dll application when using QTcpSocket

Background:
Sorry this is such a complex problem but it is driving me nuts. Finding a solution may help others who need a compartmentalized application.
I have a Qt program that is VERY compartmentalized because it is meant to host plugins and be used in a variety of situations, sometimes as a server, sometimes as a client, sometimes as both. The plugins that are loaded are login dependent. (Because the access defined for the user is not necessarily up to the user and the user's access to data and functionality may be limited).
The application relies on a core DLL library (specific to the application) which is used by the main exe, the client, the server, and all plugin dlls. Client and server functionality are also in separate dlls. I am new to this style of programming so that may be leading to my issue.
My Problem:
I have a class called "BidirectionalTcpConnection" that is defined in the core DLL which is to be used by the executable, the client dll, and the server dll. It is a class that keeps track of data that is passed back and forth over a QTcpSocket. I wrote the class to avoid THE SAME problem as I am having now except that the problem originally occurred while using the QTcpSocket.ReadAll() function AND in the current situation. (If I tried reading all but the last byte, and then read the last byte using the QTcpSocket.peek(...) function it would work fine).
My new class successfully reads from and writes to the socket without error but when I try and close or abort the socket (this happened with my earlier workaround too...), I get the same error I was getting when I tried to read it (only on the last byte). I get an Invalid address specified to RtlValidateHeap. Basically it throws a "User Breakpoint" in dbgheap.c
My Hypothesis (What I believe is wrong):
The dbgheap.c documents that it is checking to see if the address is valid and that it resides on the current heap.
It is possible that the need for compartmentalizing my application may be leading to this issue. The data being supplied to the socket for sending was originally being allocated in the executable's heap along with the instance of BidirectionalTcpConnection. (I am trying to send the login and receive the permissions for application access). The socket itself however is being allocated in the core heap (assuming that the dll has a separate heap from the exe for internal data). I tried avoiding this by doing a deep copy of each piece of data that is to be sent over the socket within the core dll code. But that hasn't solved the problem. Presumably because the BidirectionalTcpConnection is still being allocated on a separate heap from the socket itself.
My question(s) for anyone who can help:
Is the assumption in my hypothesis correct?
Do I need to allocate the socket and the connection on the same heap? How do I
overcome this issue?
Also... if you look at the code, will I need to delete the returned
string that needs to be processed by the executable within the core
dll in order to avoid the same issue?
If you guys need some code... I have supplied what I think is necessary. I can supply more upon request.
Some Code:
For starters.. here is some basic code to show the way things are allocated. The login is performed in main before the main interface is shown. w is the main interface window class instance. Here is the code that starts the process leading to the crash:
while (loginFailed)
{
splash->showLogin();
while (splash->isWaitingOnLogin())
a.processEvents();
QString username(*splash->getUserName());
QString password(*splash->getPassword());
// LATER: encrypt login for sending
loginFailed = w.loginFailed(username, password, a);
}
Here is the code that instantiates the BidirectionalTcpConnection on the executable's stack and sends the login data. This code is inside a few separate private methods of the Qt main window class.
// method A
// processes Qstring parameters into sendable data...
// then calls method B
// which creates the instance of *BidirectionalTcpConnection*
...
if (getServerAddress() == QString("LOCAL"))
mTcpConnection = new BidirectionalTcpConnection(getHostAddressIn()->toString(),
(quint16)ServerPorts::loginRequest, (long)15, this);
else
mTcpConnection = new BidirectionalTcpConnection(*getServerAddress(),
(quint16)ServerPorts::loginRequest, (long)15, this);
...
// back to method A...
mTcpConnection->sendBinaryData(*dataStream);
mTcpConnection->flushMessages(); // sends the data across the socket
...
// waits for response and then parses user data when it comes
while (waitForResponse)
{
if (mTcpConnection->hasBufferedMessages())
{
QString* loginXML = loginConnection->getNextMessageAsText();
// parse the xml
if (parseLogin(*loginXML))
{
waitForResponse = false;
}
...
}
}
...
// calls method that closes the socket which causes crash
mTcpConnection->abortConnection(); // crash occurs inside this method
delete mTcpConnection;
mTcpConnection = NULL;
Here is the relevant BidirectionalTcpConnection code in order of use. Note, this code is located in the core dll so presumably it is allocating data on a separate stack...
BidirectionalTcpConnection::BidirectionalTcpConnection(const QString& destination,
quint16 port, long timeOutInterval, TimeUnit unit, QObject* parent) :
QObject(parent),
mSocket(parent),
...
{ }
void BidirectionalTcpConnection::sendBinaryData(QByteArray& data)
{
// notice I try and avoid different heaps where I can by copying the data...
mOutgoingMessageQueue.enqueue(new QByteArray(data)); // member is of QQueue type
}
QString* BidirectionalTcpConnection::getNextMessageAsText()
// NOTE: somehow I need to delete the returned pointer to prevent memory leak
{
if (mIncomingMessageQueue.size() == 0)
return NULL;
else
{
QByteArray* data = mIncomingMessageQueue.dequeue();
QString* stringData = new QString(*data);
delete data;
return stringData;
}
}
void BidirectionalTcpConnection::abortConnection()
{
mSocket.abort(); // **THIS CAUSES ERROR/CRASH**
clearQueues();
mIsConnected = false;
}

How to access data from class in new thread in C++?

I'm trying to embed a telnet server in a data-capture program I've written. I've got both the data capture, and the telnet server working in their own classes, but now I want to transfer data from one to another, and I'm not sure where to start.
In the example below, I want to be able to send a command to the telnet server to request a data packet from the data capture thread.
So, in code (C++) this is what I want to do:
#include <thread>
void StartTelnetServer()
{
MyTelnetClass tnet;
tnet.Start(); // In here, server starts listening for connections.
}
void StartDataCapture()
{
MyDataCapture dCap;
dCap.Start(); // In here, data capture begins
}
main()
{
std::thread tnetThread(StartTelnetServer);
std::thread dCapThread(StartDataCapture);
// This will run until killed
}
I then want to telnet into it, with a string command such as "SIZE" and for the telnet class to query the latest dCap.GetSize(). There are dozen or so bits of data that I'll want to access in this way. Do I need to declare a static structure of some sort that both classes access? Am I way off base?!
This needs to run on Linux, if that matters to anything.
If the telnet handler should be able to access the data-capture object, but not the other way around, you can create both object in the main function, passing the data-capture object by reference to the telnet handler constructor. Then start the threads using the Start member functions instead.
Something like
...
class MyDataCapture;
class MyTelnetClass
{
public:
MyTelnetClass(MyDataCapture& dc)
: dCap(dc)
{}
...
private:
MyDataCapture& dCap;
...
};
...
int main()
{
MyDataCapture dCap;
MyTelnetClass tnet{dCap}
std::thread dCapThread(&MyDataCapture::Start, dCap);
std::thread tnetThread(&MyTelnetClass::Start, tnet);
...
}
This way the telnet handler can just call functions in the data-capture object when needed. Be careful through so you don't get data-races, protect data with mutexes and locks.
If you want the data-capture object to call functions in the telnet handler object as well you can't use references but have to use pointers.

AppFabric Cache standalone mode?

As an ISV I'd like to be able to program my middle tier using the AppFabric Caching Service, but then be able to deploy in small (single server) environments without the need to have AppFabric Cache Server(s) deployed. It also seems natural to me that a "in-memory only" version of the cache client would be ideal for standalone development.
However, all the research I've done so far implies that I have to load a real cache server to make some of the apis work at all, and that the current "Local" option does not fit the bill for what I want.
It seems to me that what I'm looking for would work similarly to aspx session cache, in that the out of the box mechanism is in-memory, and then you can choose to configure the older external process provider, or the sql provider, and now the AppFabric provider, giving better and better scalability as you move up. This works great for aspx session.
Am I correct in thinking that there is no equivalent solution for programming and deploying in a "small" environment for AppFabric caching?
There's a number of issues raised in this question, let's see if we can tackle them...
First and foremost, as Frode correctly points out you can run an AppFabric instance quite happily on one server - it's what I do most of the time for playing around with the API. Obviously the High Availability feature isn't going to be, well, available, but from the question itself I think you've already accepted that.
Secondly, you can't use the AppFabric API against the Local cache - the local cache is only there to save an AppFabric client trips across the wire to a dedicated AppFabric cache server.
Now, to configurable caches, which I think is the most interesting part. What I think you want to do here is separate the operations on the cache from the cache itself into a generic interface, and then you write your code against the interface at design time, and at runtime you create a cache based on information from your app.config/web.config.
So let's start by defining our interface:
public interface IGenericCache
{
void Add(string key, object value);
void Remove(string key);
Object Get(string key);
void Update(string key, object value);
}
And now we can define a couple of implementations, one using the MemoryCache and one using AppFabric.
using System.Runtime.Caching;
class GenericMemoryCache : IGenericCache
{
public void Add(string key, object value)
{
MemoryCache cache = new MemoryCache("GenericMemoryCache");
cache.Add(key, value, null, null);
}
public void Remove(string key)
{
MemoryCache cache = new MemoryCache("GenericMemoryCache");
cache.Remove(key, null);
}
public object Get(string key)
{
MemoryCache cache = new MemoryCache("GenericMemoryCache");
return cache.Get(key, null);
}
public void Update(string key, object value)
{
MemoryCache cache = new MemoryCache("GenericMemoryCache");
cache.Set(key, value, null, null);
}
}
using Microsoft.ApplicationServer.Caching;
class GenericAppFabricCache : IGenericCache
{
private DataCacheFactory factory;
private DataCache cache;
public GenericAppFabricCache()
{
factory = new DataCacheFactory();
cache = factory.GetCache("GenericAppFabricCache");
}
public void Add(string key, object value)
{
cache.Add(key, value);
}
public void Remove(string key)
{
cache.Remove(key);
}
public object Get(string key)
{
return cache.Get(key);
}
public void Update(string key, object value)
{
cache.Put(key, value);
}
}
And we could go on and write IGenericCache implementations with the ASP.NET Cache, NCache, memcached...
Now we add a factory class that uses reflection to create an instance of one of these caches based on values from the app.config/web.config.
class CacheFactory
{
private static IGenericCache cache;
public static IGenericCache GetCache()
{
if (cache == null)
{
// Read the assembly and class names from the config file
string assemblyName = ConfigurationManager.AppSettings["CacheAssemblyName"];
string className = ConfigurationManager.AppSettings["CacheClassName"];
// Load the assembly, and then instantiate the implementation of IGenericCache
Assembly assembly = Assembly.LoadFrom(assemblyName);
cache = (IGenericCache) assembly.CreateInstance(className);
}
return cache;
}
}
Anywhere the client code needs to use the cache, all that is needed is a call to CacheFactory.GetCache, and the cache specified in the config file will be returned, but the client doesn't need to know which cache it is because the client code is all written against the interface. Which means that you can scale out your caching simply by changing the settings in the config file.
Essentially what we're written here is a plugin model for caching, but be aware that you're trading off flexibility for features. The interface has to be more or less the lowest common denominator - you lose the ability to use, say, AppFabric's concurrency models, or the tagging API.
There's an excellent and more complete discussion of programming against interfaces in this article.
We have one setup where we run app fabric cache on just one server...