Sharing Ruby variables between Sinatra requests - html

I am trying to write a simple quiz game in sinatra and I need to have common objects accessible for all users (lobby state, chat messages etc.). The problem is that Sinatra reloads the code after every request and objects become in initial state. How to implement it?

Well, the topic is a bit tricky. Sinatra actually doesn't reset the server state:
require 'sinatra'
GlobalState = {}
GlobalState[:some_counter] = 0
get '/' do
response = "GlobalState[:some_counter]: #{GlobalState[:some_counter]}"
GlobalState[:some_counter] += 1
response
end
This code has nothing wrong: if you run it and go to http://localhost:4567 you will see GlobalState[:some_counter] incremented as expected.
But it is discouraged for the following reasons, that are mainly related to the web nature of the application:
Since the data is stored in a Ruby object, if you stop the server you loose the data. however, if you don't need persistent data it's not a problem
When you run a web app, usually you have simultaneous instances of your app, in order to serve multiple requests concurrently. There are a couple of ways in order to accomplish it:
Forks: multiple processes of the same application. They don't share memory, so Ruby global state variables become useless
Threads: threads share memory, so you can access to global state, but you have to manage concurrent accesses to the same global object, with non trivial consequences
You can't associate data to the user, and vice versa: this because HTTP doesn't provides methods for state preserving (it is a stateless protocol). In order to resolve it you need either:
Client-side data storing: cookies, HTML5 Local Storage...
Server-side data storing: sessions (not really server-side only, you need at least to associate sessions to the respective clients, usually storing session ids into cookies)
For these reasons the web apps data management is not trivial. Anyway don't worry, you don't have to reinvent the wheel; the solutions are in hand:
Sinatra cookies for client-side data storing
Sinatra sessions for client-server data sharing
Databases for data persistence

There isn't a way to do this without some type of persistent store. You would have to store information in either the database or cookies.

Related

How to get real time changes into a MySql Database,Database and have instant response in frontend

I am trying to build a simple project online. I have a MySql Database,Database where I will store different information, such as fake orders made from fake clients. The application will be formed by a frontend made with Javascript and HTML/CSS, while the backend will be a Node/Express API that should handle all the requests and handle the database.
I wanted to know whether there is a way to, each time a new order is made, have a refresh in my own page, and see, for example, a new column in an hypotetical table in my HTML with a minumum latency, avoiding making a request from the client every x seconds. This because it could be quite expensive in terms of bandwith and also prett unefficient.
I thought that each time I connect to the site, I get subscribed to a sort of list in the server, that broadcast a trigger to then update the frontend when tha UPDATE function is triggered in the backend. In other words, every time an update is done on the backend, the server sends a trigger to the clients that he knows are currently connected. Then, the frontend asks for the update directly.
This solutions i really complicated to handle and may be not that performant. I was thinking if there where some functionalities of the frontend or the backend or the database, or any framework that allow me to do this thing.
I would like to have all as real time as possible, using the least bandwith possible. This is because I would like to use the free tier of some online service, and I don't want to consume all the bandwith.
If you have some suggestions of framework or functionalities, or any protocol, you are welcome. Thank you a lot in advice
You can use websockets. When a user creates an order and after there is a success saving to the data base, the backend will push or publish the data to the client who is subscribed to a specific channel. The logic is not complicated at all it is called the pub/sub pattern you should search for it.
Also https://socket.io/ this is library that used on both backend and front end to deal with websockets.

Meteor performance comparison of publishing static data vs. getting data via HTTP Get request

I am building an app that receives a bunch of static data that is read only. The user does not change the data, or send any data to the server. The app just gets the data and presents it to the user in various views.
Like for example a parts list, with part numbers and prices. This data is currently stored in mongoDB.
I have few options for getting the data to the client. I could just use meteor's publication system, and have the client subscribe to the data it needs.
Or I could map all the data the client needs into one JSON file, save the JSON file to Amazon S3, and have the client make simple GET request to grab the data.
If we wanted this app to scale to many, many users, would not using meteor publication be the best? Or would either method be similar in terms of performance? Using meteor publication system would be the easiest, but I am worried that going down this route would lead to performance issues if a lot of clients request the data. If the performance between publishing and get request is about the same, I would just stick with the publication as its the easiest.
In this case Meteor will provide better performance. If your data is mostly server to client driven then clients do not have to worry about polling the server and the server will not have to worry about handling the request.
Also Meteor requires very little resources to send data to the client because the connection is persistent. Take an app like code fights which is built on Meteor constantly has thousands of connections to and from it, its performance runs great.
As a side note, if you are ready to serve your static data as a JSON file in a separate server (AWS S3), then it means you do not expect that data to be that big, so that it can be handled in a single file and entirely loaded in client's memory.
In that case, you might even want to reconsider the need to perform any separate request (whether HTTP or Meteor Pub/Sub).
For instance, simply embedding the data in your app, or served through SSR / Fast Render package.
Then if you are really concerned about your scalability, you might even reconsider the need to use Meteor, since you do not seem to need any client-server interactivity (no real need for Pub/Sub, no reactivity…). After your prototype is ready, you could rework it as a separate and static SPA, so that you do not even need to serve it through Node / Meteor.

Decoupling Client and Server - Common Patterns?

Suppose you have a mobile app that needs to ask the server for 20 other Users near your current location. The URL to get this data might look something like this (not escaped):
https://example.com/api/users?lat=40.240239&long=-111.657920&count=20
The server could then respond in one of two ways:
Return all User objects directly, as JSON, in one large array.
Return an array of UUIDs corresponding to the Users who match the request. The client would then have two choices:
a) Send a request for all User objects in one big batch:
https://example.com/api/users?ids=[1,2,3,4...]
b) Send requests for each User independently:
https://example.com/api/users?id=1
https://example.com/api/users?id=2 ...
Currently, my application implements Option #1. In the name of responsiveness, I've eliminated every possible network round-trip by returning as much data as possible in as few requests as possible. However, I'm starting to see problems with this choice due to the fact that my client and server logic are very tightly coupled. It's difficult to maintain, versioning is a nightmare, and caching on the client side is much more difficult than say, Option #2b.
Based on your experience, which option do you recommend (or a different method entirely)? What would you consider the "industry standard" way of serving data to a mobile app?

Concept clearance regarding Mobile Apps

I am new to mobile programming although I have some experience of working on web products.
I have a few concepts which I need cleared...
What is the difference between an MBAAS(Like Kii or Parse) and a data store(like MongoDB)?
How will I tie MBaas and MongoDB together? Also, if i need to connect MBaas to an RDBMS how to go about it?
On some MBaas websites I read about objects in cache getting synchronised with objects in server etc. In what shape are these cached objects? Are they JSON bodys?
Can a session be shared between an application and a browser session in the same mobile ?
Can multiple applications access the same MBaas space ? What happens if multiple applications need to access the same data base? Is it possible ?
I have an application, can it use the same cache area for storing the ids/passwords of to different users ?
Please help me as I am not getting enough documents on the internet...
Thanks in advance,
Dee.
Those are all pretty good questions when you're starting to take a look at MBaaS. I'll try to answer according to my experience:
1) MBaaS provide a higher level of abstraction that a database. It delivers higher level services instead of just persistence. Think of services like user management, analytics, push, etc on top of just data management. MBaaS almost always provide a data management service but it's higher level since it runs on top of databases like MongoDB (since MBaaS services require scalability they often rely on NoSQL databases but they do not expose the db api to you directly). Pros: you get to deal with a simpler/straightforward data management api. Cons: you don't get granular control over the data operations as seen on a db
2) To tie MBaaS to other database you need to rely on the MBaaS import/export services (I suppose that this makes sense to you after reading the first question). Pros: you don't worry about how the data is stored in an MBaaS (it will scale, have integrity, etc). Cons: you don't have a low level access to the data (you do it through the MBaaS API). But I must say MBaaS are improving a lot in what they allow you to do with the data (this is getting better)
3) maybe you read something about the offline capabilities of some MBaaS. Some of them keep operations and/or changed objects in a cache and then synchronize with the backend when online. The shape of these can vary with each MBaaS but JSON is often used when it's time to communicate with the backend (JSON is convenient for transfers of data/operations but it's not necessarily an internal representation of MBaaS client cache)
4) Not in the traditional web sense of having a session with a cookie. MBaaS usually work at the level of a user session relying on authentication services (they are particluarly strong in this area). Some MBaaS provide an anonymous user functionality where users of your app can do a session without explicit authentication (but this can't be correlated to a the same user doing an anonymous session on the web). In general you'll have to use user authentication to share web activity with MBaaS activity.
5) On the first generation of MBaaS this wasn't possible. Everything was designed thinking in independent apps. But some problems started to arise like "what if I want to share users among different apps"? So MBaaS provides are adding more services that address this sort of issues (like single sign on for multiple apps)
6) I'm not sure if I follow but if you have an application that uses an MBaaS you're probably going to use the MBaaS authentication services to login a user so the fact that you're using one device/one cache is not an issue for allowing your app to authenticate multiple users. Let me now if this is not exactly what you asked (I can edit the question)
Hope this helps you get a better picture.
Best!

Can MS Enterprise Library Logging be used for multiple applications?

I'm wondering if its - a) possible; b) good practice - to log multiple applications to single log instance?
I have several ASP.NET apps and I would like to aggregate all exceptions to a centralized location that can be queried as part of an Enterprise Dashboard app. I'm using both the EL logging block and the EL exception blog along with the Database Trace Listener. I would like to see exceptions across all apps logged to a single db.
Any comments, best practice guidelines or answers would be extremely welcome.
Yes, it is definitely possible to store multiple application logs in a central location using EL.
An Enterprise Dashboard application that lets you view exceptions across applications and tiers, and provides reporting is a great reason to centralize your logging. So I'll say yes to question b as well.
Possible Issues/Negatives
I'm assuming that you are using the Database Trace Listener since you mention that in your question. If there are a large number of applications logging a large number of log entries combined with users querying the (potentially large) log database, there is the potential for performance to degrade (since the logging is done synchronously) which could impact your application performance.
Another Approach
To mitigate against this possibility, I would investigate using the Distributor Service to log asynchronously. In that model, all of the applications would log to a message queue (using the MSMQ Trace Listener). A separate service then polls the queue and would forward the log entries to a trace listener (in your case a Database Trace Listener) which would persist the messages in your dashboard database. This setup is more complicated. But it does seem to align with what you are trying to achieve and has some other benefits such as asynchronous processing and the ability to log even if the dashboard database is down (e.g. for maintenance).
Other Considerations
You may also want to think about standardizing some LogEntry properties across applications. For example, LogEntry doesn't really have an "application" property so you could add an ExtendedProperty to represent the application name. Or you may standardize on a specific format for the Message property so that various information can be pulled out of the message and stored in separate database columns for easier searching and categorization.