Poll for Completion

User Intent

"I want to know when a feed has finished its initial sync"

Operation

  • SDK Method: graphlit.isFeedDone()

  • GraphQL: isFeedDone query

  • Entity Type: Feed

  • Common Use Cases: Wait for initial feed sync, verify feed completion before querying content

TypeScript (Canonical)

import { Graphlit } from 'graphlit-client';

const graphlit = new Graphlit();

// After creating a feed
const feedResponse = await graphlit.createFeed(feedInput);
const feedId = feedResponse.createFeed.id;

console.log(`Feed created: ${feedId}`);

// Poll for completion
const maxAttempts = 60; // 10 minutes max (60 * 10 seconds)

for (let attempts = 1; attempts <= maxAttempts; attempts++) {
  const status = await graphlit.isFeedDone(feedId);
  if (status.isFeedDone.result) {
    console.log('Feed sync complete!');

    const contents = await graphlit.queryContents({
      feeds: [{ id: feedId }],
    });

    console.log(`Synced ${contents.contents.results.length} items`);
    return;
  }

  console.log(`Still syncing... (${attempts}/${maxAttempts})`);
  await new Promise((resolve) => setTimeout(resolve, 10_000));
}

console.log('Feed sync timeout - still processing');

Python:

feed_response = await graphlit.create_feed(feed_input)
feed_id = feed_response.createFeed.id

is_done = False
attempts = 0
max_attempts = 60

while not is_done and attempts < max_attempts:
    status = await graphlit.isFeedDone(feed_id)
    is_done = status.isFeedDone.result if status.isFeedDone else False

    if not is_done:
        attempts += 1
        print(f"Still syncing... ({attempts}/{max_attempts})")
        await asyncio.sleep(10)

if is_done:
    print("Feed sync complete!")

C#:

using Graphlit;
using System.Threading.Tasks;

var graphlit = new Graphlit();

var feedResponse = await graphlit.CreateFeed(feedInput);
var feedId = feedResponse.CreateFeed.Id;

// Poll for completion (PascalCase)
bool isDone = false;
int attempts = 0;
int maxAttempts = 60;

while (!isDone && attempts < maxAttempts)
{
    var status = await graphlit.IsFeedDone(feedId);
    isDone = status.IsFeedDone?.Result ?? false;
    
    if (!isDone)
    {
        attempts++;
        Console.WriteLine($"Still syncing... ({attempts}/{maxAttempts})");
        await Task.Delay(10000); // Wait 10 seconds
    }
}

if (isDone)
{
    Console.WriteLine("Feed sync complete!");
}

Parameters

Required

  • id (string): Feed ID to check

Response

{
  isFeedDone: {
    result: boolean;  // true = sync complete, false = still syncing
  }
}

Developer Hints

Only for Initial Sync

isFeedDone() indicates initial sync completion, not ongoing monitoring:

// After feed creation
const feed = await graphlit.createFeed(feedInput);

// isFeedDone checks initial sync
await waitUntilFeedDone(feed.createFeed.id);

// After initial sync, feed continues to monitor for new content
// You don't need to call isFeedDone again

Important: Once initial sync completes, the feed continuously monitors for new content automatically.

// Too frequent (wasteful)
await new Promise(resolve => setTimeout(resolve, 1000)); //  Every 1 second

// Good balance
await new Promise(resolve => setTimeout(resolve, 10000)); //  Every 10 seconds

// For very large feeds
await new Promise(resolve => setTimeout(resolve, 30000)); //  Every 30 seconds

Why 10 seconds?: Balance between responsiveness and API efficiency. Initial feed syncs typically take 1-10 minutes depending on content volume.

🕐 Timeout Considerations

// Typical sync times by feed type
const timeouts = {
  rss: 2 minutes,          // Small: 10-100 items
  slack: 5 minutes,        // Medium: 100s-1000s of messages
  googleDrive: 10 minutes, // Large: Many files
  web: 15 minutes          // Very large: Deep crawls
};

// Adjust maxAttempts based on feed type
const maxAttempts = feedType === 'rss' ? 12 : 60; // 2 min vs 10 min

Helper Function Pattern

async function waitForFeedCompletion(
  feedId: string,
  timeoutMinutes: number = 10,
  pollIntervalSeconds: number = 10
): Promise<boolean> {
  const maxAttempts = (timeoutMinutes * 60) / pollIntervalSeconds;
  let attempts = 0;
  
  while (attempts < maxAttempts) {
    const status = await graphlit.isFeedDone(feedId);
    
    if (status.isFeedDone.result) {
      return true; // Success
    }
    
    attempts++;
    await new Promise(resolve => setTimeout(resolve, pollIntervalSeconds * 1000));
  }
  
  return false; // Timeout
}

// Usage
const completed = await waitForFeedCompletion(feedId, 10, 10);
if (completed) {
  console.log('Ready to query content');
} else {
  console.log('Timeout - feed still processing');
}

Variations

1. Basic Polling with Progress

Simple polling with progress updates:

async function pollFeedWithProgress(feedId: string) {
  console.log('Waiting for feed sync to complete...');
  
  let isDone = false;
  let attempts = 0;
  
  while (!isDone && attempts < 60) {
    const status = await graphlit.isFeedDone(feedId);
    isDone = status.isFeedDone.result || false;
    
    if (!isDone) {
      attempts++;
      const elapsed = attempts * 10; // seconds
      console.log(`⏳ ${elapsed}s elapsed...`);
      await new Promise(resolve => setTimeout(resolve, 10000));
    }
  }
  
  console.log(isDone ? ' Complete!' : '⏰ Timeout');
  return isDone;
}

2. Polling with Content Count Tracking

Track synced content during polling:

async function pollWithContentTracking(feedId: string) {
  let isDone = false;
  let previousCount = 0;
  
  while (!isDone) {
    const status = await graphlit.isFeedDone(feedId);
    isDone = status.isFeedDone.result || false;
    
    // Check how many items synced so far
    const contents = await graphlit.queryContents({
      feeds: [{ id: feedId }],
      limit: 1  // Just get count, not all items
    });
    
    const currentCount = contents.contents.results.length;
    
    if (currentCount > previousCount) {
      console.log(`📥 Synced ${currentCount} items so far...`);
      previousCount = currentCount;
    }
    
    if (!isDone) {
      await new Promise(resolve => setTimeout(resolve, 10000));
    }
  }
  
  console.log(` Sync complete! Total: ${previousCount} items`);
}

3. Parallel Feed Polling

Poll multiple feeds simultaneously:

async function pollMultipleFeeds(feedIds: string[]) {
  const pollPromises = feedIds.map(async (feedId) => {
    let isDone = false;
    
    while (!isDone) {
      const status = await graphlit.isFeedDone(feedId);
      isDone = status.isFeedDone.result || false;
      
      if (!isDone) {
        await new Promise(resolve => setTimeout(resolve, 10000));
      }
    }
    
    return feedId;
  });
  
  // Wait for all feeds to complete
  const completedFeeds = await Promise.all(pollPromises);
  console.log(`All ${completedFeeds.length} feeds synced!`);
  
  return completedFeeds;
}

// Usage
const feedIds = [feed1Id, feed2Id, feed3Id];
await pollMultipleFeeds(feedIds);

4. Exponential Backoff Polling

Reduce API calls with backoff:

async function pollWithBackoff(feedId: string) {
  let isDone = false;
  let interval = 5000; // Start at 5 seconds
  const maxInterval = 60000; // Max 60 seconds
  
  while (!isDone) {
    const status = await graphlit.isFeedDone(feedId);
    isDone = status.isFeedDone.result || false;
    
    if (!isDone) {
      console.log(`Waiting ${interval / 1000}s before next check...`);
      await new Promise(resolve => setTimeout(resolve, interval));
      
      // Exponential backoff
      interval = Math.min(interval * 1.5, maxInterval);
    }
  }
  
  console.log('Feed sync complete!');
}

5. Polling with Timeout Promise

Use Promise.race for cleaner timeout:

async function pollWithTimeout(
  feedId: string,
  timeoutMs: number = 600000 // 10 minutes
): Promise<boolean> {
  const pollPromise = (async () => {
    let isDone = false;
    
    while (!isDone) {
      const status = await graphlit.isFeedDone(feedId);
      isDone = status.isFeedDone.result || false;
      
      if (!isDone) {
        await new Promise(resolve => setTimeout(resolve, 10000));
      }
    }
    
    return true;
  })();
  
  const timeoutPromise = new Promise<boolean>((resolve) => {
    setTimeout(() => resolve(false), timeoutMs);
  });
  
  const completed = await Promise.race([pollPromise, timeoutPromise]);
  
  if (!completed) {
    console.log('⏰ Feed sync timeout');
  }
  
  return completed;
}

6. Query Content After Completion

Complete workflow from feed creation to content query:

// Create feed
const feedResponse = await graphlit.createFeed({
  name: 'News RSS',
  type: FeedTypes.Rss,
  rss: {
    uri: 'https://news.example.com/rss'
  }
});

const feedId = feedResponse.createFeed.id;

// Wait for sync
const completed = await waitForFeedCompletion(feedId);

if (completed) {
  // Query synced content
  const contents = await graphlit.queryContents({
    feeds: [{ id: feedId }],
    orderBy: OrderByTypes.CreationDate,
    orderDirection: OrderDirectionTypes.Desc,
    limit: 10
  });
  
  console.log('Latest synced items:');
  contents.contents.results.forEach((item, index) => {
    console.log(`${index + 1}. ${item.name}`);
  });
}

Common Issues

Issue: isFeedDone() always returns false Solution: Feed may be stuck. Check feed state with getFeed(). Look for error state.

Issue: Polling times out but feed has content Solution: Feed may be partially synced but not "done". Increase timeout or query content anyway.

Issue: Feed not found error Solution: Verify feed ID is correct. Check that feed wasn't deleted.

Issue: Feed completes immediately (no content synced) Solution: Check feed configuration. May have OAuth token issues or incorrect settings.

Issue: Memory leak from long polling Solution: Ensure you have proper timeout/max attempts. Don't poll indefinitely.

Production Example

Poll helper function:

async function waitForFeed(feedId: string, maxMinutes: number = 10): Promise<boolean> {
  const maxAttempts = maxMinutes * 6; // 6 checks per minute (10s intervals)
  let attempts = 0;
  
  while (attempts < maxAttempts) {
    const status = await graphlit.isFeedDone(feedId);
    
    if (status.isFeedDone.result) {
      return true;
    }
    
    attempts++;
    await new Promise(resolve => setTimeout(resolve, 10000));
  }
  
  return false;
}

// Usage
const feedId = response.createFeed.id;
const success = await waitForFeed(feedId, 10);

if (success) {
  const contents = await graphlit.queryContents({ feeds: [{ id: feedId }] });
  console.log(`Synced ${contents.contents.results.length} items`);
}

Last updated

Was this helpful?