Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Is it safe to use Thread.sleep in a module?

  1. Default Is it safe to use Thread.sleep in a module?

    In my application, I need to wait for certain conditions to be true before allowing Wowza to return m3u8 responses for live streams.

    What I'd like to do is use Thread.sleep in my module's onHTTPSessionCreate method... sleeping for 1 second then testing the conditions again, but I don't know if that will interfere with the application or the Vhost.

    Input please? Is this safe, or is there a better way of going about this?

    Thanks,
    Jay

  2. #2
    Join Date
    Dec 2007
    Posts
    21,962

    Default

    Jay,

    I guess try it out. I don't know a better server-side only solution. You might try a client-server solution, where you keep bouncing back and forth until you are ready on the server.

    Richard

  3. Default

    Thanks Richard.

    In this case, I client/server approach isn't an option, as I won't always have control of the client side application.

    I've been testing with Thread.sleep in my onHTTPSessionCreate method, and it seems that it doesn't cause immediate problems.... but I'd really hate to put this into production to find out I've introduced potential for problems by doing so.

    That said, I was previously using Thread.sleep in my onAppStart handler, and that -did- seem to cause problems (caused output problems described in a thread I posted previously).

    Some definitive input from engineering on this one would be really helpful. Knowing if the calls to onHTTPSessionCreate are on the same thread as the application (or if each HTTPSession is running this method on its own thread) would clear up a lot of questions.
    Last edited by jay_charles; 03-12-2012 at 08:08 AM.

  4. #4

    Default

    It is not a good idea to sleep in onHTTPSessionCreate. It will create all sorts of threading issues internally in the server. It will also most likely cause socket timeout issues. All I can suggest is that you do your operation in the background and call reject session asynchronously. It should kill the session mid-stream.

    Charlie

  5. Default

    Thanks Charlie.

    Maybe if I provide additional information your can give me some suggestions...

    I'm pulling in live streams from an origin RTMP server (FMIS) by creating a Stream (using Stream.createInstance), then setting up a MediaCasterStreamItem to pull from the origin, and finally playing the MediaCaster's IMediaStream over the Stream (the client subscribe to the Stream).

    In cases where the first client to the edge instance is an HLS client, if I don't wait until the cupertino packetizer on the Stream has had time to build up a couple of packets before accepting the HTTPSession, I have problems getting the stream to the client. In the case of iOS, I end up with failures to play (broken play button icon), and in the case of Roku clients, the stream will play for a short time, and then the application goes back into a "loading" state and never recovers. This only happens to the first client to hit the application instance when that client is an HLS client... once the instance is up and running and the packetizer has had time to build up a few packets, additional HLS clients have no problem.

    To deal with this, I'm trying to postpone the m3u8 response from the server for a short time when that first client is an HLS client, and only when the Stream hasn't had time to get a few HLS packets ready. m3u8 responses for HLS clients that come on after the Stream is ready do not need to be postponed. I got around socket timeouts by cranking up the timeout config values to 60 seconds, but from your comment it's clear that using Thread.sleep is not the way to go here.

    Any ideas or suggestions? Is there any way to defer accepting the the httpSession so I can handle it outside of the onHTTPSessionCreate method? It seems that if I don't accept or reject in onHTTPSessionCreate, Wowza rejects it for me.
    Last edited by jay_charles; 03-12-2012 at 08:36 AM.

  6. Default

    Ok... revised approach.

    Instead of using Thread.sleep in the onHTTPSessionCreate, I've created a new class that extends Thread... let's call it TestThread. TestThread has a member function (let's call it isReady() ) that contains a while loop that checks the value of a local variable. If the local var is true, or if the loop has been running for N seconds or more, the loop exits and isReady returns true. If the local var is false, the thread sleeps for N milliseconds, and then runs the while loop again.

    In my onHTTPSessionCreate method, if needed, I will instantiate an instance of TestThread, start it, and invoke isReady(). So, rather than using Thread.sleep() in onHTTPSessionCreate, I'm just waiting for a return value from TestThread::isReady() before allowing onHTTPSessionCreate to complete.

    Any better, or am I still looking for trouble here?
    Last edited by jay_charles; 03-12-2012 at 09:53 AM.

  7. #7

    Default

    FYI, a loop is the same as a delay. It halts code execution until completion. Charlie made a suggestion. On the other hand it seems you identified some issue, and a solution. If you're pausing for a short time, it could be ok. Try it out.

  8. Default

    Yes, but unfortunately the suggestion Charlie made doesn't really work in my use case, as it has nothing to do with being able to reject a session. If the application hasn't had time to connect up to the origin stream as described above, it creates potential for the first client on one of my edge server instances to fail to receive the stream, even if the stream is up and running on the origin.

    So, I guess I'll deploy this way, and see where it takes us. I don't see any other option than to stop execution for a few seconds in these cases, as I can't let that m3u8 response go out until the stream is ready to go.

  9. #9

    Default

    Quote Originally Posted by jay_charles View Post
    Ok... revised approach.

    Instead of using Thread.sleep in the onHTTPSessionCreate, I've created a new class that extends Thread... let's call it TestThread. TestThread has a member function (let's call it isReady() ) that contains a while loop that checks the value of a local variable. If the local var is true, or if the loop has been running for N seconds or more, the loop exits and isReady returns true. If the local var is false, the thread sleeps for N milliseconds, and then runs the while loop again.

    In my onHTTPSessionCreate method, if needed, I will instantiate an instance of TestThread, start it, and invoke isReady(). So, rather than using Thread.sleep() in onHTTPSessionCreate, I'm just waiting for a return value from TestThread::isReady() before allowing onHTTPSessionCreate to complete.

    Any better, or am I still looking for trouble here?
    This method creates the same problem. It still will hang the thread. We have had several folks try to setup dynamic packetization like you describe above and it never really works very well. It just takes too much time. User's usually feel the stream is broken. I really am not sure what to suggest other than to ahve the origin stay connected to the source stream.

    Charlie

  10. Default

    Thanks Charlie. I appreciate the input

    Truthfully, an always-on edge stream won't work well for our use case. Since our network can have dozens of of edge servers at any given time (both dedicated and Ec2 instances), and any subscribing client can potentially land on any of those edge servers at any time, it would be unreasonable to have every origin stream pushing out to every edge at all times (we can have hundreds of origin streams at any given time, so the network cost of repeating all origin streams to all edges needlessly would be astronomical).

    For the short term, I'll have to take my chances with hanging the thread and hope for the best, as I don't have any other options. Based on my tests thus far, it's not proving to be a problem... I guess we'll see what happens when we're in a production situation.

    Hopefully you'll be able to add something in a future release that will be a more proper solution. Since it's only really an issue when the first client hitting the edge is an HLS client, and I only have to delay the m3u8 response during the first 15 - 30 seconds of the origin stream being connected to the edge, the frequency with which this happens is not all that great. Fortunately, the vast majority of our current traffic is still RTMP, but I imagine that will change over time.

    Since you've had other users looking for a solution to this problem, is there any possibility that this issue can be addressed in a not so distant update? It's understandable that those early HLS clients will have to wait a bit longer for the stream to start (I don't expect any way around that), but the ability to defer the acceptance or rejection of HTTP sessions somehow without compromising server performance would certainly help in our use case.
    Last edited by jay_charles; 03-13-2012 at 06:52 AM.

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 1
    Last Post: 12-04-2013, 07:35 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •