I run my web app using Amazon EC2 servers and use TweetInvi to maintain a user and filtered twitter stream. I need the streams to be running 24/7.
I am using the StreamStopped event to keep the stream running continuously as described here:
How to keep streaming continuously - Tweetinvi
I am starting the stream in my startup class by using hangfire (http://hangfire.io/) to maintain the stream connection in the background but happy to do this any other way.
My application is kept alive 24/7 if no users connect.
However, after a while, with no exception raised, the streams stop.
Is there a better way to maintain and keep alive a stream?
My keep-alive function wasn't actually working 100% and so my application sometimes died during the night when no users connected hence the StreamStopped event wasn't called. I now use Uptime Robot to hit my site every minute keeping it alive.
Related
I'm currently seeing delays of 2-3 seconds on my first requests coming into our APIs.
We've set the min instances to 1 to prevent cold start but this a delay is still occurring.
If I check the metrics I don't see any startup latencies in the specified timeframe so I have no insights in what is causing these delays. Tracing gives the following:
The only thing I can change, is switching to "CPU is always allocated" but this isn't helping in any way.
Can somebody give more information on this?
As mentioned in the Answer :
As per doc :
Idle instances As traffic fluctuates, Cloud Run attempts to reduce the
chance of cold starts by keeping some idle instances around to handle
spikes in traffic. For example, when a container instance has finished
handling requests, it might remain idle for a period of time in case
another request needs to be handled.
Cloud Run But, Cloud Run will terminate unused containers after some
time if no requests need to be handled. This means a cold start can
still occur. Container instances are scaled as needed, and it will
initialize the execution environment completely. While you can keep
idle instances permanently available using the min-instance setting,
this incurs cost even when the service is not actively serving
requests.
So, let’s say you want to minimize both cost and response time latency
during a possible cold start. You don’t want to set a minimum number
of idle instances, but you also know any additional computation needed
upon container startup before it can start listening to requests means
longer load times and latency.
Cloud Run container startup There are a few tricks you can do to
optimize your service for container startup times. The goal here is to
minimize the latency that delays a container instance from serving
requests. But first, let’s review the Cloud Run container startup
routine.
When Starting the service
Starting the container
Running the entrypoint command to start your server
Checking for the open service port
You want to tune your service to minimize the time needed for step 1a.
Let’s walk through 3 ways to optimize your service for Cloud Run
response times.
1. Create a leaner service
2. Use a leaner base image
3. Use global variables
As mentioned in the Documentation :
Background activity is anything that happens after your HTTP response
has been delivered. To determine whether there is background activity
in your service that is not readily apparent, check your logs for
anything that is logged after the entry for the HTTP request.
Avoid background activities if CPU is allocated only during request processing
If you need to set your service to allocate CPU only during request
processing, when the Cloud Run service finishes handling a
request, the container instance's access to CPU will be disabled or
severely limited. You should not start background threads or routines
that run outside the scope of the request handlers if you use this
type of CPU allocation. Review your code to make sure all asynchronous
operations finish before you deliver your response.
Running background threads with this kind of CPU allocation can create
unpredictable behavior because any subsequent request to the same
container instance resumes any suspended background activity.
As mentioned in the Thread reason could be that all the operations you performed have happened after the response is sent.
According to the docs the CPU is allocated only during the request processing by default so the only thing you have to change is to enable CPU allocation for background activities.
You can refer to the documentation for more information related to the steps to optimize Cloud Run response times.
You can also have a look on the blog related to use of Google API Gateway with Cloud Run.
I have an ASP.NET MVC web application that uses the Quartz.net library to execute tasks on a daily schedule. I found out pretty quickly that IIS terminates/suspends the app pool after a period of inactivity. I have changed the config for that app pool to avoid this behavior, as follows:
Start Mode: Always Running
Idle Time Out (minutes): 0
Idle Time Out Action: Suspend
Generate Recycle Log Entry: True [for all sub-properties]
Regular Time Interval: 0
Specific Time Interval: TimeSpan[] Array [empty]
The only possible property I could see that might still kill my app is
Ping Enabled: True
It is set to kill any worker processes that don't respond within 90 seconds.
I am hesitant to change this property because I don't want to introduce resource leaks or anything like that.
These changes seemed to work for the past few days, but my job failed to execute again this morning.
So my question is, what can I look for in the event viewer or elsewhere that would indicate that the process/app was suspended or terminated?
I am not asking for how to improve my implementation - I am aware that a Windows Service or scheduled task, with persistent storage, would be better. I want to understand why this is happening, and where to look to find out when and why the app pool has stopped or started. I can't seem to find anything in the event viewer but perhaps I am looking in the wrong place.
Thanks in advance.
Would it be possible that there were unhanded exceptions which could crash the appPool. I think such things can be seen from Event Viewer.
This is my situation:
Im using sendAsynchronousRequest. I quickly relized that it has a default timeout of 60 seconds. My app is designed to wait for an opponent to start the game (its a word-game).
Actually, it could take hours before the opponent starts the game. Which means the async-request could be waiting for hours.
Is that bad? I mean, I can probably change the default timeout. But the question is if this iss a bad design. The thing is that I wanted to avoid pulling the server at intervals to know if the opponent has started the match or not.
If this is a bad design: can somebody suggest an alternativ way?
Your best bet is to poll the server if you want to be up and running quickly and don't have a lot of resources (time/money).
If for some reason you need more real-time then there is a high amount of complexity involved in creating an open socket to your server for communication and you are best off using an existing framework like Pusher ($), PubNub ($) or socket.io (free but you will have to handle the server side). If you want to create your own client/server notification system then you may want to check out SocketRocket from Sqaure which provides a client side WebSocket implementation for iOS.
I'm writing a TCP server in Erlang, using Ranch. The clients will reconnect immediately the connection is dropped, which means that one particular failure mode is listeners being started and killed dozens of times a second.
I'd like to detect this happening and publish statistics to statsd, for monitoring in production.
So, can I use something in Ranch to monitor when a listener is recycled? Or can I use something in Erlang to monitor process mortality for the entire node, without having to link to each process, and where those processes were started by some other supervisor, so I don't have a reference to them?
It's not a direct answer to my question, but I opted, instead, to have a separate process periodically polling ranch_server:count_connections(my_ref), and publish that to statsd.
I have a backend Rails server with Sidekiq, which serves as API server. The app works as follow:
My Rails server receives many requests from incoming API clients at the same time.
For each of these requests, the Rails server will allocate jobs to a Sidekiq server. Sidekiq server makes requests to external APIs (such as Facebook) to get data, and analyze it and return a result to Rails server.
For example, if I receive 10 incoming requests from my API clients, for each request, I need to make 10 requests to external API servers, get data and process it.
My challenge is to make my app responds to incoming requests concurrently. That is, for each incoming request, my app should process in parallel: make calls to external APIs, get data and return result.
Now, I know that Puma can add concurrency to Rails app, while Sidekiq is multi-threaded.
My question is: Do I really need Sidekiq if I already have Puma? What would be the benefit of using both Puma and Sidekiq?
In particular, with Puma, I just invoke my external API calls, data processing etc. from my Rails app, and they will automatically be concurrent.
Yes, you probably do want to use Puma and Sidekiq. There are really two issues at play here.
Concurrency (as it seems you already know) is the number of web requests that can be handled simultaneously. Using an app server like Puma or Unicorn will definitely help you get better concurrency than the default web brick server.
The other issue at play is the length of time that it takes your server to process a web request.
The reason that these two things are related is that number or requests per second that your app can process is a function of both the average processing time for each request and the number of worker processes that are accepting requests. Say your average response time is 100ms. Then a single web worker can process 10 requests per second. If you have 5 workers, then you can handle 50 requests per second. If your average response time is 500ms, then you can handle 2 reqs/sec with a single worker, and 10 reqs/sec with 5 workers.
Interacting with external APIs can be slow at times, and in the worst cases it can be very unreliable with unresponsive servers on the remote end, or network outages or slowdowns. Sidekiq is a great way to insulate your application (and your end users) from the possibility that the remote API is responding slowly. Imagine that the remote API is running slowly for some reason and that the average response time from it has slowed down to 2 seconds per request. In that case you'd only be able to handle 2.5 reqs/sec with 5 workers. With anymore traffic than that your end users might start to have a long wait time before any page on your app could respond, even those that don't make remote API calls, because all of your web workers might be waiting for the slow remote API to respond. As traffic continues to increase your users would start getting connection timeouts.
The idea with using Sidekiq is that you separate the time spent waiting on the external API from your web workers. You'd basically take the request for data from your user, pass it to Sidekiq, and then immediately return a response to the user that basically says "we're processing your request". Sidekiq can then pick up the job and make the external request. After it has the data it can save that data back into your application. Then you can use web sockets to push a notification to the user that the data is ready. Or even push the data directly to them and update the page accordingly. (You could also use polling to have the page continually asking "is it ready yet?", but that gets very inefficient very quickly.)
I hope this makes sense. Let me know if you have any questions.
Sidekiq, like Resque and Delayed Job, is designed to provide asynchronous job processing from a queue.
If you don't need jobs to be queued up and run asynchronously, there's no substantial benefit (or harm) to using Sidekiq.
If the tasks need to run synchronously (which it sounds like you might—it's not clear if clients are waiting for data or just requesting that jobs run), Sidekiq and its relatives are likely the wrong tool for the job. There is no guaranteed processing time when using Sidekiq or other solutions; jobs are pushed onto the end of the stack, however long that may be, and won't be processed until their turn comes up. If clients are waiting for data, they may time out long before your worker pool ever processes their jobs.