Skip to content

Commit b4fa03c

Browse files
fix: reduce daemon idle polling and memory use
1 parent 74de29c commit b4fa03c

13 files changed

Lines changed: 151 additions & 43 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "lay"
3-
version = "0.1.219"
3+
version = "0.1.220"
44
edition = "2021"
55
description = "Alpha Double Shift RU/EN layout rescue for Linux desktops"
66
license = "MIT"

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ curl -fsSL https://raw.githubusercontent.com/radislabus-star/lay-public/main/scr
4444
По умолчанию double Shift исправляет **1 последнее слово**. Области `2 слова`
4545
и `3 слова` можно включить отдельно в трее.
4646

47+
## Что нового в 0.1.220
48+
49+
- исправлен idle busy-loop в non-GNOME backend: `lay-daemon` больше не
50+
зацикливает `poll()` на 1 мс из-за stale focus-poll timestamp;
51+
- настройки демона кешируются по `mtime` с коротким интервалом проверки, чтобы
52+
горячий путь не читал `~/.config/lay/config.json` на каждом цикле;
53+
- русские горячие словари упакованы компактнее: текущая память свежего демона
54+
снизилась примерно со 168 МБ до 139 МБ после прогрева.
55+
4756
## Что нового в 0.1.219
4857

4958
- исправлен Niri/backend-кейс без `focused_window_identity`: при смене

VERSIONING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ number from `git rev-list`.
1313

1414
Current publication branch version:
1515

16-
- `0.1.219`
16+
- `0.1.220`
1717

1818
Do not rely on commit counts. Before publishing or pushing, run the bump script
1919
or verify the version fields manually.

extension/lay@radislabus-star.github.io/metadata.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"uuid": "lay@radislabus-star.github.io",
33
"name": "Lay Layout Switcher",
4-
"version": 219,
5-
"version-name": "0.1.219",
4+
"version": 220,
5+
"version-name": "0.1.220",
66
"description": "Alpha GNOME Shell extension для lay-daemon. Показывает EN/RU в трее, переключает раскладку по клику. Минимальный DBus bridge для layout activation и fallback text insert.",
77
"shell-version": ["45", "46", "47", "50"],
88
"url": "https://github.com/radislabus-star/lay-public"

extension/lay@radislabus-star.github.io/prefs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import Gtk from 'gi://Gtk';
66
import {ExtensionPreferences} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
77

88
const CONFIG_PATH = GLib.get_home_dir() + '/.config/lay/config.json';
9-
const APP_VERSION = '0.1.219';
10-
const APP_RELEASE_DATE = '2026-06-07';
9+
const APP_VERSION = '0.1.220';
10+
const APP_RELEASE_DATE = '2026-06-11';
1111
const APP_URL = 'https://github.com/radislabus-star/lay-public';
1212
const APP_ICON_NAME = 'input-keyboard-symbolic';
1313
const HEADER_ICON_SIZE = 16;

extension/lay@radislabus-star.github.io/settings.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import GLib from 'gi://GLib';
44
import Gtk from 'gi://Gtk';
55

66
const CONFIG_PATH = GLib.get_home_dir() + '/.config/lay/config.json';
7-
const APP_VERSION = '0.1.219';
8-
const APP_RELEASE_DATE = '2026-06-07';
7+
const APP_VERSION = '0.1.220';
8+
const APP_RELEASE_DATE = '2026-06-11';
99
const APP_URL = 'https://github.com/radislabus-star/lay-public';
1010
const APP_ICON_NAME = 'input-keyboard-symbolic';
1111
const HEADER_ICON_SIZE = 16;

extension/lay@radislabus-star.github.io/tray_support.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ export const STATS_PATH = GLib.get_home_dir() + '/.local/share/lay/stats.json';
66
export const RECENT_ACTIONS_PATH = GLib.get_home_dir() + '/.local/share/lay/recent_actions.jsonl';
77
export const PROJECT_DIR = GLib.get_home_dir() + '/projects/lay';
88
export const UPDATE_LOG_PATH = GLib.get_home_dir() + '/.local/state/lay/update.log';
9-
export const APP_VERSION = '0.1.219';
9+
export const APP_VERSION = '0.1.220';
1010
export const APP_DESCRIPTION = 'Альфа: RU/EN-переключатель по двойному Shift и помощь при наборе';
11-
export const APP_RELEASE_DATE = '2026-06-07';
11+
export const APP_RELEASE_DATE = '2026-06-11';
1212
export const APP_LICENSE = 'MIT';
1313
export const APP_URL = 'https://github.com/radislabus-star/lay-public';
1414
export const APP_PLATFORM = 'Linux: GNOME, KDE, Niri, Wayland, X11';

src/bin/lay_daemon/config_runtime.rs

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,89 @@
11
use lay::config::{CorrectionEngine, LayConfig};
22
use lay::desktop::LayoutBackend;
33
use lay::text_backend::TextBackendPreference;
4+
#[cfg(not(test))]
5+
use std::path::PathBuf;
6+
#[cfg(not(test))]
7+
use std::sync::Mutex;
48
use std::sync::OnceLock;
9+
#[cfg(not(test))]
10+
use std::time::{Duration, Instant, SystemTime};
511

612
use super::{detect_auto_layout_backend_hint, ENTER_AUTOCORRECT_EXPERIMENT_ENV};
713

814
static AUTO_LAYOUT_BACKEND_HINT: OnceLock<Option<LayoutBackend>> = OnceLock::new();
915

16+
#[cfg(not(test))]
17+
const CONFIG_CACHE_CHECK_INTERVAL: Duration = Duration::from_millis(250);
18+
19+
#[cfg(not(test))]
20+
struct CachedLayConfig {
21+
config: LayConfig,
22+
modified: Option<SystemTime>,
23+
checked_at: Instant,
24+
}
25+
26+
#[cfg(not(test))]
27+
static CONFIG_CACHE: OnceLock<Mutex<CachedLayConfig>> = OnceLock::new();
28+
29+
fn current_config() -> LayConfig {
30+
#[cfg(test)]
31+
{
32+
LayConfig::load()
33+
}
34+
#[cfg(not(test))]
35+
{
36+
let cache = CONFIG_CACHE.get_or_init(|| {
37+
Mutex::new(CachedLayConfig {
38+
config: LayConfig::load(),
39+
modified: config_modified_at(),
40+
checked_at: Instant::now(),
41+
})
42+
});
43+
let mut cache = cache
44+
.lock()
45+
.unwrap_or_else(|poisoned| poisoned.into_inner());
46+
if cache.checked_at.elapsed() < CONFIG_CACHE_CHECK_INTERVAL {
47+
return cache.config.clone();
48+
}
49+
50+
cache.checked_at = Instant::now();
51+
let modified = config_modified_at();
52+
if modified != cache.modified {
53+
cache.config = LayConfig::load();
54+
cache.modified = modified;
55+
}
56+
cache.config.clone()
57+
}
58+
}
59+
60+
#[cfg(not(test))]
61+
fn config_modified_at() -> Option<SystemTime> {
62+
std::fs::metadata(config_path())
63+
.and_then(|metadata| metadata.modified())
64+
.ok()
65+
}
66+
67+
#[cfg(not(test))]
68+
fn config_path() -> PathBuf {
69+
let home = std::env::var("HOME").unwrap_or_default();
70+
PathBuf::from(home).join(lay::config::CONFIG_PATH)
71+
}
72+
1073
pub(super) fn active_replace_words() -> usize {
11-
LayConfig::load().active_replace_words()
74+
current_config().active_replace_words()
1275
}
1376

1477
pub(super) fn active_typing_assist_words() -> usize {
15-
LayConfig::load().active_typing_assist_words()
78+
current_config().active_typing_assist_words()
1679
}
1780

1881
pub(super) fn active_correction_engine() -> CorrectionEngine {
19-
LayConfig::load().active_correction_engine()
82+
current_config().active_correction_engine()
2083
}
2184

2285
pub(super) fn active_layout_backend() -> LayoutBackend {
23-
let config = LayConfig::load();
86+
let config = current_config();
2487
let backend = config.active_layout_backend();
2588
let configured = config.layout_backend.trim().to_ascii_lowercase();
2689
if configured != "auto" {
@@ -34,19 +97,19 @@ pub(super) fn active_layout_backend() -> LayoutBackend {
3497
}
3598

3699
pub(super) fn active_text_backend() -> TextBackendPreference {
37-
LayConfig::load().active_text_backend()
100+
current_config().active_text_backend()
38101
}
39102

40103
pub(super) fn active_auto_replace() -> bool {
41-
LayConfig::load().auto_replace
104+
current_config().auto_replace
42105
}
43106

44107
pub(super) fn active_typing_assist() -> bool {
45-
LayConfig::load().typing_assist
108+
current_config().typing_assist
46109
}
47110

48111
pub(super) fn active_enter_autocorrect() -> bool {
49-
let cfg = LayConfig::load();
112+
let cfg = current_config();
50113
active_enter_autocorrect_from_env(
51114
cfg.enter_autocorrect,
52115
std::env::var(ENTER_AUTOCORRECT_EXPERIMENT_ENV)
@@ -73,22 +136,22 @@ pub(super) fn active_enter_autocorrect_from_env(
73136
}
74137

75138
pub(super) fn active_auto_switch_layout() -> bool {
76-
LayConfig::load().auto_switch_layout
139+
current_config().auto_switch_layout
77140
}
78141

79142
pub(super) fn active_learning_log() -> bool {
80-
LayConfig::load().learning_log
143+
current_config().learning_log
81144
}
82145

83146
pub(super) fn active_lem_enabled_for_scope(word_count: usize) -> bool {
84-
LayConfig::load().lem_enabled_for_scope(word_count)
147+
current_config().lem_enabled_for_scope(word_count)
85148
}
86149

87150
#[cfg(not(test))]
88151
pub(super) fn active_typing_assist_pipeline_for_auto_replace(
89152
context: &str,
90153
) -> Vec<lay::config::TypingAssistRuleConfig> {
91-
let cfg = LayConfig::load();
154+
let cfg = current_config();
92155
lay::typing_context::typing_assist_pipeline_for_context(
93156
cfg.auto_replace,
94157
cfg.active_correction_safety(),

src/bin/lay_daemon/focus_guard.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,13 @@ fn poll_focused_window_state_after(
5151
last_poll: &mut Instant,
5252
min_interval: Duration,
5353
) -> Option<FocusedWindowState> {
54-
if active_layout_backend() != LayoutBackend::Gnome || last_poll.elapsed() < min_interval {
54+
if last_poll.elapsed() < min_interval {
5555
return None;
5656
}
5757
*last_poll = Instant::now();
58+
if active_layout_backend() != LayoutBackend::Gnome {
59+
return None;
60+
}
5861
focused_window_state()
5962
}
6063

0 commit comments

Comments
 (0)