2021-06-05 20:17:08+00:00

In high-churn data tracking platforms, clients register and delete millions of ephemeral task records daily. If your database schema allocates standard 64-bit auto-incrementing integer IDs to these documents, you will consume ID space rapidly. While 64-bit ID exhaustion seems unlikely, Google App Engine's NDB ID generator skips ranges to avoid conflicts, hastening exhaustion risks. Building a recycler registry allows us to reclaim and reallocate deleted entity IDs safely.

By utilizing transaction-safe locks and recycling registries in Cloud Datastore, we can prevent entity ID space exhaustion.


1. Creating the Reclaimable ID Registry

We define a Datastore entity model to track recycled IDs and implement transaction-safe functions to claim them during write tasks:

# id_recycler.py
from google.cloud import ndb

class RecycledId(ndb.Model):
    # Store reclaimed integer keys
    reclaimed_id = ndb.IntegerProperty(required=True)
    reclaimed_at = ndb.DateTimeProperty(auto_now_add=True)

class EphemeralTask(ndb.Model):
    task_name = ndb.StringProperty()
    created_at = ndb.DateTimeProperty(auto_now_add=True)

@ndb.transactional(xg=True)
def allocate_next_task_id(task_name):
    # Query for an available recycled ID
    query = RecycledId.query().order(RecycledId.reclaimed_at)
    available_id_entity = query.get()
    
    if available_id_entity:
        target_id = available_id_entity.reclaimed_id
        # Delete from registry to prevent double allocation
        available_id_entity.key.delete()
        print(f"Allocating recycled ID: {target_id}")
    else:
        # Fall back to standard ID generation if registry is empty
        target_id = None
        
    # Create the task entity
    if target_id:
        task_key = ndb.Key(EphemeralTask, target_id)
        task = EphemeralTask(key=task_key, task_name=task_name)
    else:
        task = EphemeralTask(task_name=task_name)
        
    task.put()
    return task.key.id()

2. Reclaiming IDs on Document Deletion

When a document is marked for deletion, we write its ID to the recycler registry within the same transaction to guarantee data integrity.