Pausing FilteredStream, adding tracks, then resuming stops stream

Sep 13, 2014 at 3:56 AM
Hi -

I having a little trouble adding tracks to a running filtered stream. Based on previous research, the approach seems to be pausing, adding tracks, and then resuming. Doing this stops the filteredstream unexpectedly.

Would you mind advising? Here's the exception - "Specified argument was out of the range of valid values. Parameter name: index".

Source : System.Core

at System.Linq.Enumerable.ElementAt[TSource](IEnumerable1 source, Int32 index)
at Tweetinvi.Streams.Helpers.StreamTrackManager
1._matchingTracks(String input)
at Tweetinvi.Streams.Helpers.StreamTrackManager`1.GetMatchingTracksAndActions(String input)
at Tweetinvi.Streams.FilteredStream.<StartStreamMatchingAnyConditionAsync>b__c(String json)
at Tweetinvi.Streams.Helpers.StreamResultGenerator.<>c__DisplayClass1.<StartStreamAsync>b__0(String json)
at Tweetinvi.Streams.Helpers.StreamResultGenerator.<StartStreamAsync>d__7.MoveNext()


My code:
   private void queryNotificationReceived(object sender, EventArgs e)
    {
        var required = _Flow.GetRequiredData();

        lock (queryList)
        {
            queryList = required.queries.ToList();
            stream.PauseStream();
            stream.Tracks.Clear();

            foreach (var q in queryList){
                stream.AddTrack(q.QueryValue);
            }

            stream.ResumeStream();
        }

    }
Thanks for your help!
Coordinator
Sep 14, 2014 at 1:10 AM
Hi there,

The problem that you have is that you are pausing the stream instead of stopping the stream.
When you add a track, you need to restart the stream because only when you call .StartStream Tweetinvi creates the WebRequest.

Pausing a stream means that you only put it on hold but you need to respect the fact that you are not authorized to change the tracks within it because Twitter will continue to send you the information from the tracks of the initial query.

So what you want to do is the following:
    private void queryNotificationReceived(object sender, EventArgs e)
    {
        var required = _Flow.GetRequiredData();

        lock (queryList)
        {
            queryList = required.queries.ToList();
            stream.StopStream();
            stream.ClearTracks();

            foreach (var q in queryList){
                stream.AddTrack(q.QueryValue);
            }

            stream.ResumeStream();
        }
    }
Linvi
Coordinator
Sep 14, 2014 at 1:12 AM
I have just added Exception that will now be thrown when trying to modify the tracks while the stream is not stopped.
This will be added to the coming Tweetinvi 0.9.4.0.

Linvi
Sep 14, 2014 at 2:04 AM
Thanks for getting back Linvi.

I've made the suggested change and unfortunately no luck in resuming. There aren't any Exceptions being thrown, but the stream doesn't seem to be "connected" anymore. Even removing the adding of tracks, I'm simply trying stream.StopStream() followed by a stream.ResumeStream(). For some reason the stream won't start back up.

It's declared as a private variable in the class:
private Tweetinvi.Core.Interfaces.Streaminvi.IFilteredStream stream;

And is being started on a separate thread:
var t = new Thread( () => stream.StartStreamMatchingAnyCondition() );
t.Start();

Could accessing the stream from a different thread be causing the issue? Can you confirm that calling StopStream() and ResumeStream() multiple times functions as expected on your end?

Thanks helping me out
Editor
Sep 14, 2014 at 3:41 AM
Edited Sep 14, 2014 at 3:42 AM
I just tested and this works:
private Tweetinvi.Core.Interfaces.Streaminvi.IFilteredStream stream;

private void StartStreamWithTracks(params string[] tracks)
{
    if (stream != null && stream.StreamState == StreamState.Resume)
    {
        try
        {
            stream.StopStream();
        }
        catch (Exception)
        {
            // Do something
        }
    }
    stream = Stream.CreateFilteredStream();
    foreach (var track in tracks)
    {
        stream.AddTrack(track);
    }
    //stream.MatchingTweetReceived += (o, args) => DoSomething();
    var t = new Thread(() => stream.StartStreamMatchingAnyCondition());
    t.Start(); 
}

private void queryNotificationReceived(object sender, EventArgs e)
{
    var required = _Flow.GetRequiredData();

    lock (queryList)
    {
        StartStreamWithTracks(required.queries.ToArray());
    }
}
Marked as answer by linvi on 9/14/2014 at 5:08 AM
Coordinator
Sep 14, 2014 at 12:08 PM
Sorry, I got it wrong with the ResumeTrack. ResumeTrack should be used for PausedStream while StartStream should be used for StoppedStream.
Please follow the example of imlokesh which is very good.

Linvi
Sep 14, 2014 at 10:20 PM
Thanks Imlokesh & Linvi, this did the trick!