Creating object in Sinatra app that maintains data on new HTTP requests - ruby

I'm building a very simple app using Sinatra. I am not required to use persistent storage so I'm not using a database; however, I want to keep an object that contains a record of all my transactions. The object should not reinitialize when there is a new HTTP request.
I have tried putting a #transactions variable into an initialize method and I've tried set :transactions, Transactions.new, both in my controller (neither of which worked). I just tried
configure do
##transactions = Transactions.new
end
and it's still saying the object is nil (the Transactions initialize method doesn't use params and initializes all instance variables, so nothing should be nil).
Are there other ways to accomplish this?

What you want is persistent storage. I know that you're trying to avoid it but you should perhaps just bite the bullet.
You could invent one from scratch like for example using a JSON file on the file system but thats not really going to save you any time. Better yet is to use a memory based storage like memcached, or an actual database like SQLite.
Using a class variable is a dead end since they are not thread safe and will not actually persist after the program ends.

Related

mapdb as a request scoped globally available state store?

has anyone used mapdb as a state store in spring boot for a request lifecycle ?
I mean set things like "isDebug", etc in mapdb for the particular request and then clear it out at the end of the request ?
mapdb sounds very much like how Redux, etc is used in React, so im trying to leverage similar patterns.
if you have done so, how do you manage the flushing of data at the end of a request, etc ?
how do you manage the flushing of data at the end of a request
The documentation of MapDb is rather sparse, but at a first glance DB.close() seems to close the current transaction and write data to files, if it is actually backed by a file, which I guess you mean by "flushing".
Of course this begs the question why you would want to perma
I'd assume it destroys an in memory database
Note: Just as M. Deinum I don't really see what you expect to gain from using mapdb.

Realm: Do we need to write each and every new RLMObject we create

Started using Realm as storage layer for my app. This is these scenario I am trying to solve
Scenario: I get a whole bunch of data from the server. I convert each piece of data into a RLMObject. I want to just "save" to persistent storage at the end. In between, I want these RLMObjects create dot reflected when I do a query
I don't see a solution for this in Realm. Looks like only way to is to write each Object back into the Realm DB after they are created. Documentation also says that writes are expensive. Is there any way around?
To reduce the overhead, I guess I could maintain list of objects created and write all of them in one transaction. Still seems like a lot of work. Is that how it is intended to be used?
You can create the objects as standalone without adding them to the Realm, and then add them all in single transaction (which is very efficient) at the end.
Check out the documentation about creating objects here: https://realm.io/docs/objc/latest/#creating-objects
There is also an example of adding objects in bulk here, where they get added in chunks so that other threads can observe the changes as they happens: https://realm.io/docs/objc/latest/#using-a-realm-across-threads

Why we send id instead of whole object in workers?

In Ruby practice is to send id instead of object in workers. Isn't that kind of CPU consuming process because we have to retrieve Object again from database.
Several reasons:
Saves space on the queue, also transfer time (app => queue, queue => workers).
Often it is easier to fetch fresh object from the database (as opposed to retrieving cached copy from the queue)
Argument to Resque.enqueue must be JSON-serializable. Complex objects not always can be serialized.
If you think about it the reasons are pretty obvious:
your object may change between the time te action is queued and handled and in general you don't want an outdated object.
an id a a lot lighter to transport than a whole object which you will need to serialize it in json/yaml or anything else.
if you need the associations the problem just got even worse :)
But in the end it depends on your application, if you only need some informations you can just send them to your worker directly without even using the full model.

Jruby persistence problem

I want to store objects in jruby for a short time. The objects use procs so I seem to have trouble storing it into db. If anyone has good ideas for how to persist jruby objects for 1-5 mins it would be great.
These objects are quite large, specifically, celerity browser objects.
For now, I have created a model in jruby like so:
class Persist
##persistHash ||= Hash.new
def self.storeItem(id, item)
##persistHash[id.to_s] = item
end
def self.getItem(id)
return ##persistHash[id.to_s]
end
end
I have warbled the app and deployed it to glassfish v2.
I run the program and it works fine for a while. But after a day, if I call 'get' right after 'store' (10-20 secs) I am returned nil.
I can't find any errors in logs.
EDIT: I have also found that the item is indeed inserted into the hashtable (the hashtable did not run out of memory during insert):
Before 24 hrs:
Persist.storeItem() followed by Persist.getItem() works fine.
A http call for store. Then another http call for get returns the object.
After 24 hrs:
Persist.storeItem() followed by Persist.getItem() works fine.
A http call for store. Then another http call for get returns nil.
I don't see the object being deleted at any point.
I would examine the JVM using other tools. It could very well be that you've exhausted memory but the log message / exception never gets created to report the memory exhaustion.
May I suggest hooking up JMX monitoring of the various heap regions and create a means by which the hash can purged of old objects.
Wish I had more for you. Good luck!

object session in playframework

How I can store an instance object foreach user session?
I have a class to modeling a complex algorithm. This algorithm is designed to run step-by-step. I need to instantiate objects of this class for each user. Each user should be able to advance step by step their instance.
You can only store the objects in the Cache. The objects must be serializable for this. In the session you can store a key (which must be a String) to the Cache. Make sure that your code still works if the object was removed from the cache (same as a session-timeout). It's explained in http://www.playframework.org/documentation/1.0.3/cache.
Hope that solve your problem.
To store values in the session:
//first get the user's session
//if your class extends play.mvc.Controller you can access directly to the session object
Session session = Scope.Session.current();
//to store values into the session
session.put("name", object);
If you want to invalidate / clear the session object
session.clear()
from play documentation: http://www.playframework.org/documentation/1.1.1/cache
Play has a cache library and will use Memcached when used in a distributed environment.
If you don’t configure Memcached, Play will use a standalone cache that stores data in the JVM heap. Caching data in the JVM application breaks the “share nothing” assumption made by Play: you can’t run your application on several servers, and expect the application to behave consistently. Each application instance will have a different copy of the data.
You can put any object in the cache, as in the following example (in this example from the doc http://www.playframework.org/documentation/1.1.1/controllers#session, you use session.getId() to save messages for each user)
public static void index() {
List messages = Cache.get(session.getId() + "-messages", List.class);
if(messages == null) {
// Cache miss
messages = Message.findByUser(session.get("user"));
Cache.set(session.getId() + "-messages", messages, "30mn");
}
render(messages);
}
Because it's a cache, and not a session, you have to take into account that the data might no longer be available, and have some mean to retrieve it once again from somehere (the Message model, in this case)
Anyway, if you have enough memory and it involves a short interaction with the user the data should be there, and in case it's not you can redirect the user to the beginning of the wizard (you are talking about some kind of wizard page, right?)
Have in mind that play, with it's stateless share-nothing approach, really have no sessión at all, underneath it just handles it through cookies, that's why it can only accept strings of limited size
Here's how you can save "objects" in a session. Basically, you serialize/deserialize objects to JSON and store it in the cookie.
https://stackoverflow.com/a/12032315/82976

Resources