How does Google App Engine Instance hours counted in this particular situation? - google-app-engine

I got an app built on top of App Engine.
We got a User class and many other classes as well. When user loged in.
How Google count the Instance hours when I do the following:
User user=request.getParameter("user");
I also have public static variable to hold chat messages & that could be called every 5 seconds if a user enter chat room (note: if many users enter the chat room then that variable could be called many times every 5 seconds), as the following:
public static Map<User, ConcurrentHashMap<User, CopyOnWriteArrayList<String>>> chatRoomConcurrentMap=new ConcurrentHashMap<User, ConcurrentHashMap<User, CopyOnWriteArrayList<String>>>();
If that is the case then how Google count the instance hours of that static variable?
SO, How does Google count instance hour when we instantiate an object and when we call a public variable?

Instance hours calculations are done based on app instance uptime and instance class, not on particular object instantiation or variable access inside the app's code.
If your app receives requests less than 15 minutes apart it will be billed (in terms of instance hours) at least as a constantly up instance (more if multiple instances are alive at the same time).

Related

ndb query on Google Cloud Platform intermittently returning nothing

I have a Python application deployed on Google Cloud Platform. There is a Google Cloud Datastore in the background, with two Kinds. I use NDB to pull the data into the application.
class AttEvent(ndb.Model):
event = ndb.StringProperty()
matchdate = ndb.DateTimeProperty()
class MainPage(webapp2.RequestHandler):
def get(self):
query = AttEvent.query().order(AttEvent.matchdate)
for q in query.fetch():
try:
# application code
One of the Kinds (AtEvent in the code above) is causing me trouble. The app will deploy and work as expected for hours / days, but then intermittently stop returning data. Debugging shows the q object is legitimate object of the type AttEvent, but for each of the items in the values collection, it says "(Object has no fields)". When the application code attempts to reference a property of the model (i.e. q.event), it fails.
The query will suddenly start working again, minutes / hours later, even if I take no action. I can't see any pattern or apparent cause. Obviously this isn't ideal from a user perspective.
The Kind that is causing trouble is static data and only actually contains 3 entities. The other Kind is transactional, contains thousands of records, but has never exhibited the same behaviour.
The intermittent nature of the fault leads me to believe this is something to do with caching, but I am fairly new to Python and GCP, so I am not exactly sure. I've tried doing a context.clear_cache() before the query, but it has no effect.
Am I missing something obvious?
I don't know why this is happening, but I have a possible work around. Since the data is static and the entities seem to be small, you could store them in instance memory instead of querying for them every time you need them.
Store the entities in a module level variable like this:
att_entities = AttEvent.query().order(AttEvent.matchdate).fetch()
class AttEvent(ndb.Model):
event = ndb.StringProperty()
matchdate = ndb.DateTimeProperty()
class MainPage(webapp2.RequestHandler):
def get(self):
for q in att_entities:
try:
# application code
You would get the entities only when a new instance is launched so as long as it works the first time you are all set. As a bonus, it will make the get call faster since you don't need to retrieve the data from the data store.
You might need to add extra logic to cause att_entities to be updated as needed.

How to keep track of chat messages seen by user

I am building a simple Chat App using Firebase and Ionic. I am trying to keep track of number of messages that are unread for different groups that the user is member of (like WhatsApp).
I have the messages linked to $scope through $firebaseArray
$scope.messages = $firebaseArray(<ref to message path in firebase>);
$scope.messages is iterated over and shown in the view. When a new message arrives it automatically shows up in the group being viewed. I want to keep track of messages not viewed. I am not quite sure of the best way to keep track of which messages the user has seen. I see suggestions here to keep track of timestamp when a user last visited a group but am wondering if there is a better/simpler solution to this.
The things that come to mind that I need to do are -
Setup some sort of monitoring for all groups the user is member of not just the one being viewed by the user. If user is member of 50 groups I need to monitor all 50 of them individually (wonder what, if any, performance implications that has). Here I will need to setup a child_added monitoring for each of the groups the user is member of
Track timestamp for last time a user was in a group
As the user switches groups, change the $firebaseArray to monitor the new group and cancel the $firebaseArray setup for the previous. Change the child_added monitoring for the new group to the group being viewed previously
If the user moves to another part of the app where he is not looking at any group messages (perhaps in a setting section) then again be aware of that and monitor all groups - remove the firebeaseArray from the group last being viewed and add a child_added monitoring when user moves away
If the user goes to another application and pushes the Chat application in the background then I am a little unsure of what to do
How does the code determine that the group whose messages the user was looking at is no longer active and new messages coming in now need to be counted
I am assuming I need to monitor for the App Pause and Resume events to address that. Is there a better way?
Trying to keep my code simple but feels like monitoring for unread messages is a significant chunk of work. Thanks for any ideas or pointers to sample code or to simplify this.
-S

How to cut down API requests in AngularJS app

My problem is I'm making too many API requests, which I want to cut down if possible. Below I'll describe the situation:
I have three pages, all linked using ngRoute. Like this:
Page A: Teams (list of teams)
URL: "/teams"
Page B: Team Details (list of players)
URL: "/teams/team-details"
Page C: Player Details (list of player stats)
URL: "/teams/team-details/player-details"
Page A is populated by pulling an array of the teams from an API very easily using a simple $resource.query() request, and using ng-repeat to iterate through them.
Page B is populated by calling an html template and populating specific fields with values from a separate API request to the /team-details endpoint, taking the team_id value from the clicked element on Page A.
Page C (as with page B) takes a player_id from the clicked player on Page B and calls the /player-details endpoint using that value. This is yet another separate request.
This all works fine, but as you can imagine, a single user could quite easily rack up in excess of 100 API requests within an hour.
I have a request limit of 1000/hour, so if a mere 10 users are online at the same time, it could easily exceed my limit and shut down my API.
If I could access the API as one single master endpoint that outputted all data and subdata in one set, then that would solve my problem, but since I need to request separate endpoints I can't see how to do this.
Is there a better way to approach this? Or are these excessive API requests the only way?
Any help would be appreciated.
As far as I can see, Your model looks suitable for the application and meets how an API-driven application should work...
However, One potential cut-down you could make is to cache some of the results locally. i.e. store a local version of some of the data that is unlikely to change within a session. For example, If the number of teams is unlikely to change, then store the results of 1 API request locally and use that instead of recalling data from your API.
Following on from this route, you could choose to only update certain data after a certain time period. So, if a user has looked at some team-details then refuse to update this data for the next 10-20minutes. However, this does again depend how time-sensitive your data is.

Flurry Analytics Dashboard -- Display Duration of Timed Events

On the Flurry Dashboard, is there a way to compare the total duration of 2 (or more) different timed events?
For example, suppose an application logs distinct timed events for different screens (i.e. Screen1, Screen2, Screen3, etc.) starting the timed event when the screen appears and ending the timed event when the screen disappears. We would like a way to visually compare the total amount of time for each of the events on a single graph of some sort. (We would also like to see the average total amount of time per session on a single graph) This would give us a quick understanding of what percentage of time our users are spending on different screens within the app.
I've played with the dashboard but I can't seem to find a way to do this. It seems like it is not possible to show the duration of timed events on the dashboard. So the only way to view event duration is to look at individual events in isolation in the Events section.
Hopefully I'm missing something, so thanks in advance for any answers to this question.

Google App Engine + Objectify: Register object once?

I recently got objectify working with app engine, but I'm having trouble with registering a class for objectify multiple times. While developing in Eclipse, which recompiles and runs again every time the localhost is refreshed, the script that registers the student is run multiple times, and crashes the program after just one refresh.
<%
//In my main.jsp file, which is the main interactive html page
ObjectifyService.register(Object.class);
%>
How can I ensure that this script is only run once? Is there a way to check if a class is registered with objectify? I followed a suggestion on another stackoverflow thread to do the following:
public class Object {
...
static {
ObjectifyService.register(Object.class);
}
...
}
This gave me a different error. How can I solve this?
Put it on your ServletContextListener, specifically, on the contextInitialized() hook. This will ensure that the Objectify register code is only executed once when the server is warming up.
by looking on a reliable example like this:
Objectify in JSP
you can find similar attempt to register the class, BUT... Read the comments from the example:
// BE CAREFUL with this line! This a example, but in a real world project, you should look a better
// place for register an entity, at the very beginning of your application is recommended.
So... You probably have a java class in which you implemented several methods like: get/put/delete etc... and in that java class you should place the code to register the class
static {
ObjectifyService.register(Object.class);
}
OR, look for some other place that is being called once upon the application starts

Resources