Skip to content

Commit

Permalink
Merge pull request #159 from googlefonts/simplify-external-change
Browse files Browse the repository at this point in the history
Adjust to external change protocol
  • Loading branch information
justvanrossum authored Mar 14, 2024
2 parents a69e73d + 49fa859 commit bdbca81
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/fontra_rcjk/backend_fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def __init__(self, path: PathLike, *, create: bool = False):
self._recentlyWrittenPaths: dict[str, Any] = {}
self._tempGlyphCache = TimedCache()
self.fileWatcher: FileWatcher | None = None
self.fileWatcherCallbacks: list[Callable[[Any, Any], Awaitable[None]]] = []
self.fileWatcherCallbacks: list[Callable[[Any], Awaitable[None]]] = []

async def aclose(self) -> None:
self._tempGlyphCache.cancel()
Expand Down Expand Up @@ -231,7 +231,7 @@ async def putCustomData(self, customData: dict[str, Any]) -> None:
customDataPath.write_text(json.dumps(customData, indent=2), encoding="utf-8")

async def watchExternalChanges(
self, callback: Callable[[Any, Any], Awaitable[None]]
self, callback: Callable[[Any], Awaitable[None]]
) -> None:
if self.fileWatcher is None:
self.fileWatcher = FileWatcher(self._fileWatcherCallback)
Expand All @@ -245,7 +245,7 @@ async def _fileWatcherCallback(self, changes: set[tuple[Change, str]]) -> None:
reloadPattern = await self.processExternalChanges(changes)
if reloadPattern:
for callback in self.fileWatcherCallbacks:
await callback(None, reloadPattern)
await callback(reloadPattern)

async def processExternalChanges(self, changes) -> dict | None:
glyphNames = set()
Expand Down
30 changes: 17 additions & 13 deletions src/fontra_rcjk/backend_mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from random import random
from typing import Any, Awaitable, Callable

from fontra.backends.designspace import makeGlyphMapChange
from fontra.core.classes import (
GlobalAxis,
GlobalDiscreteAxis,
Expand Down Expand Up @@ -426,18 +425,18 @@ async def _watchExternalChangesLoop(self):
errorDelay = 30
while True:
try:
externalChange, reloadPattern = await self._pollOnceForChanges()
reloadPattern = await self._pollOnceForChanges()
except Exception as e:
logger.error("error while polling for changes: %r", e)
traceback.print_exc()
logger.info(f"pausing the poll loop for {errorDelay} seconds")
await asyncio.sleep(errorDelay)
else:
if externalChange or reloadPattern:
if reloadPattern:
for callback in self.watcherCallbacks:
await callback(externalChange, reloadPattern)
await callback(reloadPattern)

async def _pollOnceForChanges(self) -> tuple[Any, Any]:
async def _pollOnceForChanges(self) -> dict[str, Any] | None:
try:
await asyncio.wait_for(
self._pollNowEvent.wait(),
Expand All @@ -449,17 +448,17 @@ async def _pollOnceForChanges(self) -> tuple[Any, Any]:
self._pollNowEvent.clear()
if self._lastPolledForChanges is None:
# No glyphs have been requested, so there's nothing to update
return None, None
return None
if self._writingChanges:
# We're in the middle of writing changes, let's skip a round
return None, None
return None
response = await self.client.glif_list(
self.fontUID,
updated_since=fudgeTimeStamp(self._lastPolledForChanges),
)
responseData = response["data"]
glyphNames = set()
glyphMapUpdates: dict[str, list[int] | None] = {}
haveGlyphMapUpdates = False
latestTimeStamp = "" # less than any timestamp string

for glyphInfo in responseData.get("deleted_glifs", []):
Expand All @@ -474,7 +473,7 @@ async def _pollOnceForChanges(self) -> tuple[Any, Any]:
continue

logger.info(f"Found deleted glyph {glyphName}")
glyphMapUpdates[glyphName] = None
haveGlyphMapUpdates = True
del self._glyphMap[glyphName]
del self._rcjkGlyphInfo[glyphName]
latestTimeStamp = max(latestTimeStamp, glyphInfo["deleted_at"])
Expand Down Expand Up @@ -506,7 +505,7 @@ async def _pollOnceForChanges(self) -> tuple[Any, Any]:
codePoints = _codePointsFromGlyphInfo(glyphInfo)
if codePoints != self._glyphMap.get(glyphName):
self._glyphMap[glyphName] = codePoints
glyphMapUpdates[glyphName] = codePoints
haveGlyphMapUpdates = True

glyphNames.add(glyphName)
self._glyphCache.pop(glyphName, None)
Expand All @@ -516,9 +515,14 @@ async def _pollOnceForChanges(self) -> tuple[Any, Any]:

self._lastPolledForChanges = latestTimeStamp

reloadPattern = {"glyphs": dict.fromkeys(glyphNames)} if glyphNames else None
externalChange = makeGlyphMapChange(glyphMapUpdates)
return externalChange, reloadPattern
reloadPattern: dict[str, Any] = (
{"glyphs": dict.fromkeys(glyphNames)} if glyphNames else {}
)

if haveGlyphMapUpdates:
reloadPattern["glyphMap"] = None

return reloadPattern


def _codePointsFromGlyphInfo(glyphInfo: dict) -> list[int]:
Expand Down

0 comments on commit bdbca81

Please sign in to comment.