Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions syncserver/staticnode.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@
Column("client_state", String(32), nullable=False),
Column("created_at", BigInteger(), nullable=False),
Column("replaced_at", BigInteger(), nullable=True),
Column("keys_changed_at", BigInteger(), nullable=True),
Column("node", String(255), nullable=True),
Index('lookup_idx', 'email', 'service', 'created_at'),
)


_GET_USER_RECORDS = sqltext("""\
select
uid, generation, client_state, created_at, replaced_at
uid, generation, client_state, created_at, replaced_at,
keys_changed_at, node
from
users
where
Expand All @@ -64,9 +67,11 @@
_CREATE_USER_RECORD = sqltext("""\
insert into
users
(service, email, generation, client_state, created_at, replaced_at)
(service, email, generation, client_state, created_at, replaced_at,
keys_changed_at, node)
values
(:service, :email, :generation, :client_state, :timestamp, NULL)
(:service, :email, :generation, :client_state, :timestamp, NULL,
:keys_changed_at, :node)
""")


Expand Down Expand Up @@ -125,7 +130,7 @@ def __init__(self, sqluri, node_url, **kw):
self._engine = create_engine(sqluri, **sqlkw)
users.create(self._engine, checkfirst=True)

def get_user(self, service, email):
def get_user(self, service, email, **kw):
params = {'service': service, 'email': email}
res = self._engine.execute(_GET_USER_RECORDS, **params)
try:
Expand All @@ -140,7 +145,8 @@ def get_user(self, service, email):
'generation': row.generation,
'client_state': row.client_state,
'first_seen_at': row.created_at,
'old_client_states': {}
'old_client_states': {},
'keys_changed_at': row.keys_changed_at,
}
# Any subsequent rows are due to old client-state values.
old_row = res.fetchone()
Expand All @@ -163,11 +169,13 @@ def get_user(self, service, email):
finally:
res.close()

def allocate_user(self, service, email, generation=0, client_state=''):
def allocate_user(self, service, email, generation=0, client_state='',
keys_changed_at=0, **kw):
now = get_timestamp()
params = {
'service': service, 'email': email, 'generation': generation,
'client_state': client_state, 'timestamp': now
'client_state': client_state, 'timestamp': now,
'keys_changed_at': keys_changed_at, 'node': self.node_url,
}
res = self._engine.execute(_CREATE_USER_RECORD, **params)
res.close()
Expand All @@ -178,10 +186,12 @@ def allocate_user(self, service, email, generation=0, client_state=''):
'generation': generation,
'client_state': client_state,
'first_seen_at': now,
'old_client_states': {}
'old_client_states': {},
'keys_changed_at': keys_changed_at,
}

def update_user(self, service, user, generation=None, client_state=None):
def update_user(self, service, user, generation=None, client_state=None,
keys_changed_at=0, node=None, **kw):
if client_state is None:
# uid can stay the same, just update the generation number.
if generation is not None:
Expand Down Expand Up @@ -209,13 +219,16 @@ def update_user(self, service, user, generation=None, client_state=None):
'service': service, 'email': user['email'],
'generation': generation, 'client_state': client_state,
'timestamp': now,
'keys_changed_at': keys_changed_at, 'node': node,
}
res = self._engine.execute(_CREATE_USER_RECORD, **params)
res.close()
user['uid'] = res.lastrowid
user['generation'] = generation
user['old_client_states'][user['client_state']] = True
user['client_state'] = client_state
user['keys_changed_at'] = keys_changed_at
user['node'] = node
# Mark old records as having been replaced.
# If we crash here, they are unmarked and we may fail to
# garbage collect them for a while, but the active state
Expand Down