Polling in Software Systems

 

Polling in Software Systems

Polling is a technique where a system repeatedly checks for changes or new data at regular intervals. It is often used when event-driven notifications (e.g., WebSockets, SQL Server notifications) are not available or feasible.


1. Types of Polling

a) Regular Polling (Fixed Interval)

  • The system checks for updates at a fixed time interval (e.g., every 10 seconds).
  • Simple to implement but can cause unnecessary load if updates are infrequent.

🔹 Example:
A background service in .NET Core checking for new database records every minute.

public class PollingService : BackgroundService
{
    private readonly ILogger<PollingService> _logger;

    public PollingService(ILogger<PollingService> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Checking for updates...");
            CheckForUpdates();  // Replace with actual data check logic
            await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
        }
    }

    private void CheckForUpdates()
    {
        // Query the database or API to check for changes
        _logger.LogInformation("Polling database...");
    }
}

Pros:

  • Simple to implement.
  • No external dependencies.

Cons:

  • Wastes resources when there are no changes.
  • Database or API load increases with shorter intervals.

b) Adaptive Polling (Backoff Strategy)

  • Dynamically adjusts polling frequency based on system activity.
  • If no changes occur, polling slows down (e.g., from 5 sec → 10 sec → 30 sec).

🔹 Example:
If the last 5 polls detected no changes, increase the delay.

public class AdaptivePollingService : BackgroundService
{
    private readonly ILogger<AdaptivePollingService> _logger;
    private int _pollingInterval = 5000;  // Start with 5 seconds
    private int _missedUpdates = 0;

    public AdaptivePollingService(ILogger<AdaptivePollingService> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            bool dataChanged = CheckForUpdates();

            if (dataChanged)
            {
                _pollingInterval = 5000;  // Reset to 5 seconds
                _missedUpdates = 0;
            }
            else
            {
                _missedUpdates++;
                if (_missedUpdates >= 5) _pollingInterval = Math.Min(_pollingInterval * 2, 60000); // Max 60 sec
            }

            await Task.Delay(_pollingInterval, stoppingToken);
        }
    }

    private bool CheckForUpdates()
    {
        // Simulate checking database for updates
        _logger.LogInformation("Checking for updates...");
        return new Random().Next(0, 10) < 2;  // Simulate a 20% chance of change
    }
}

Pros:

  • Reduces unnecessary database queries.
  • Improves performance & efficiency.

Cons:

  • Delayed responses if updates occur after a long backoff.
  • More complex than fixed interval polling.

c) Long Polling

  • The client sends a request to the server and waits until a change occurs.
  • If the server detects a change, it immediately responds.
  • If no change occurs within a timeout (e.g., 30 sec), the server responds empty, and the client retries.

🔹 Example:
Long polling to get real-time notifications from a REST API.

[HttpGet("long-polling")]
public async Task<IActionResult> LongPolling(CancellationToken cancellationToken)
{
    while (!cancellationToken.IsCancellationRequested)
    {
        if (CheckForUpdates())  // If data changed, return response
            return Ok(new { message = "New data available!" });

        await Task.Delay(5000, cancellationToken);  // Wait before checking again
    }
    return NoContent();
}

Pros:

  • Real-time updates without constant requests.
  • Reduces unnecessary polling when no updates exist.

Cons:

  • Requires holding HTTP connections, which can be inefficient for large-scale applications.

2. Polling in Different Scenarios


3. Polling in .NET Core with Caching

🔹 Example: Polling SQL Server and caching the results in MemoryCache.

public class DatabasePollingService : BackgroundService
{
    private readonly IMemoryCache _cache;
    private readonly string _connectionString;
    private DateTime _lastUpdated = DateTime.MinValue;

    public DatabasePollingService(IMemoryCache cache, IConfiguration config)
    {
        _cache = cache;
        _connectionString = config.GetConnectionString("DefaultConnection");
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            await RefreshCacheIfNeeded();
            await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
        }
    }

    private async Task RefreshCacheIfNeeded()
    {
        using var connection = new SqlConnection(_connectionString);
        using var command = new SqlCommand("SELECT MAX(LastModified) FROM Products", connection);
        connection.Open();
        
        var lastModified = (DateTime?)await command.ExecuteScalarAsync();
        if (lastModified > _lastUpdated)
        {
            _lastUpdated = lastModified ?? DateTime.MinValue;
            _cache.Remove("ProductsCache");  // Clear cache
        }
    }
}

4. Polling vs Event-Driven Alternatives


5. When to Use Polling?

✔️ When event-driven options are not available.
✔️ When the data doesn’t change often (adaptive polling).
✔️ When you need simple implementation without extra dependencies.

❌ Avoid polling when real-time performance is required.
❌ Avoid polling when server load is a concern (use SQL Dependency or SignalR instead).


Conclusion

  • Fixed polling is simple but wastes resources.
  • Adaptive polling improves efficiency by dynamically adjusting the interval.
  • Long polling provides real-time-like behavior without excessive requests.
  • Consider event-driven solutions like SQL Dependency, WebSockets, or message queues for better performance.

Comments

Popular posts from this blog

Maxpooling vs minpooling vs average pooling

Understand the Softmax Function in Minutes

Percentiles, Deciles, and Quartiles