Skip to content

Commit ea846c7

Browse files
committed
[refactor] autosave is now working!
1 parent a22c842 commit ea846c7

File tree

1 file changed

+70
-70
lines changed

1 file changed

+70
-70
lines changed

py/visdom/server.py

+70-70
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ def safe_join_with_none(x,y):
168168

169169

170170
STORES = {}
171-
172171
def NIF(*a,**kw): raise NotImplementedError()
173172
class StoragePrototype(object):
174173

@@ -206,13 +205,19 @@ def callback_after_setitem(state, key, v):
206205

207206
# @staticmethod
208207
@classmethod
209-
def atomic_dump_json(self, xdir, key, x):
210-
xdir = B.safe_dir(xdir)
211-
env_path_file = os.path.join(xdir, "{0}.json".format(key))
212-
with open(env_path_file+".temp", 'w') as f:
208+
# def atomic_dump_json(self, xdir, key, x):
209+
def atomic_dump_json(self, fn, x):
210+
'''
211+
All i know about the file is its extension
212+
'''
213+
target_file = fn +'.json'
214+
# xdir = B.safe_dir(xdir)
215+
# target_file = B.SJN(xdir,key)+'.json'
216+
# env_path_file = os.path.join(xdir, "{0}.json".format(key))
217+
with open(target_file+".temp", 'w') as f:
213218
f.write(json.dumps(x))
214-
shutil.move(env_path_file+'.temp',env_path_file)
215-
return env_path_file
219+
shutil.move(target_file+'.temp',target_file)
220+
return target_file
216221

217222
@classmethod
218223
def _serialize_env_list_(self, state, eids, env_path, schema):
@@ -226,27 +231,36 @@ def _serialize_env_list_(self, state, eids, env_path, schema):
226231
tree = self.serialize_env_single(state, env_id, env_path, schema)
227232
return env_ids
228233

229-
json._dumps_old = json.dumps
230-
231-
class CustomEncoder(json.JSONEncoder):
232-
def default(self, obj):
233-
if isinstance(obj, LazyContainerPrototype):
234-
return obj._raw_dict
235-
return super().default(obj)
236-
237-
def dumps(*a,**kw):
238-
kw['cls'] = CustomEncoder
239-
return json._dumps_old(*a,**kw)
240-
json.dumps = dumps
241-
242-
# f.write(json.dumps(x,cls=self.CustomEncoder))
243-
244234

245235

236+
if 1:
237+
'''
238+
Override json.dumps()
239+
'''
240+
json._dumps_old = json.dumps
241+
class CustomEncoder(json.JSONEncoder):
242+
def default(self, obj):
243+
if isinstance(obj, LazyContainerPrototype):
244+
return obj._raw_dict
245+
return super().default(obj)
246+
247+
def dumps(*a,**kw):
248+
kw['cls'] = CustomEncoder
249+
return json._dumps_old(*a,**kw)
250+
json.dumps = dumps
251+
252+
# f.write(json.dumps(x,cls=self.CustomEncoder))
246253
# @staticmethod
247254
# def serialize_all(state, env_path=DEFAULT_ENV_PATH):
248255
# serialize_env_list(state, list(state.keys()), env_path=env_path)
249256

257+
def legacy_save_children(x):
258+
if isinstance(x, LazyContainerPrototype):
259+
# import pdb; pdb.set_trace()
260+
x.save_children()
261+
else:
262+
pass
263+
250264

251265
@dset(STORES)
252266
class SimpleJsonStorage(StoragePrototype):
@@ -297,7 +311,6 @@ def get_valid_env_list(fn):
297311
return ret
298312

299313
# [i for i in os.listdir(env_path) if '.json' in i]
300-
301314
# @staticmethod
302315
@classmethod
303316
def serialize_env_single(cls, state, env_id, env_path, schema):
@@ -309,7 +322,9 @@ def serialize_env_single(cls, state, env_id, env_path, schema):
309322
x['reload']
310323
x['jsons']
311324
# os.makedirs(tree) if not os.path.exists(tree) else None
312-
cls.atomic_dump_json(env_path, env_id, x)
325+
# cls.atomic_dump_json(env_path, env_id, x)
326+
cls.atomic_dump_json(B.SJN(env_path,env_id),x)
327+
# (env_path, env_id, x)
313328
'''
314329
This function save serialized data to disk
315330
@@ -322,11 +337,8 @@ def serialize_env_single(cls, state, env_id, env_path, schema):
322337
- key exists,
323338
- mtime equals to the mtime
324339
and mtime equals to the stored mtime, then
325-
'''
326340
327-
328-
'''
329-
This was unsafe: use .temp to make sure atomicity
341+
Old saving was unsafe: use .temp to make sure atomicity
330342
'''
331343

332344
SCHEMAS = {}
@@ -354,7 +366,6 @@ def map_schema(self,par_schema,key):
354366
@classmethod
355367
def legacy_load_state(self, state, env_path, LazyEnvData):
356368
pass
357-
358369
# @staticmethod
359370
# def cast_to_schema(v, schema):
360371
# if schema == 'file':
@@ -367,7 +378,6 @@ def legacy_load_state(self, state, env_path, LazyEnvData):
367378
# else:
368379
# raise NotImplementedError(f'cast_to_schema({schema!r})')
369380
# return
370-
371381
@classmethod
372382
def callback_before_setitem(self, state, key, v):
373383
'''
@@ -383,7 +393,9 @@ def callback_before_setitem(self, state, key, v):
383393
# v = self.cast_to_schema(v, state.schema[key])
384394
return v
385395

386-
396+
@staticmethod
397+
def add_extension(fn):
398+
return fn+'.json'
387399
@classmethod
388400
def lazy_read_file_xt(self, tree, par, key, xt):
389401
'''
@@ -417,12 +429,13 @@ def lazy_read_file_xt(self, tree, par, key, xt):
417429
else:
418430
assert key is not None
419431
fn = B.J(tree,key)
420-
# if not os.path.exists(fn):
421-
# xxo = {}
422-
# logging.debug(f'lazy_read_file_xt({tree!r}, {key!r}):Empty file!')
423-
# else:
424-
xxo = self.safe_parse_json(fn)
425-
logging.debug(f'lazy_read_file_xt({tree!r}, {key!r})')
432+
fn = self.add_extension(fn)
433+
if not os.path.exists(fn):
434+
xxo = {}
435+
logging.debug(f'lazy_read_file_xt({tree!r}, {key!r}):Empty file!')
436+
else:
437+
xxo = self.safe_parse_file(fn)
438+
logging.debug(f'lazy_read_file_xt({tree!r}, {key!r})')
426439

427440
elif xt=='vstate':
428441
if xxo is None: xxo = {}
@@ -476,11 +489,12 @@ def write_key_value_xt(cls, tree, key, data, xt):
476489
ret = []
477490
if xt == 'file':
478491
'single file '
479-
assert key is not None, f'Not allowed for type {xt!r}'
492+
# assert key is not None, f'None not allowed write_key_value_xt({tree!r}, {key!r},{xt!r})'
480493
# assert data.__len__()
481494
# if data.__len__()==0:
482495
# import pdb; pdb.set_trace()
483-
rett = cls.atomic_dump_json(tree, key, data)
496+
# rett = cls.atomic_dump_json(tree, key, data)
497+
rett = cls.atomic_dump_json(B.SJN(tree,key),data)
484498
ret.append( rett )
485499
logging.debug(f'write_key_value_xt({tree!r}, {key!r})')
486500

@@ -558,10 +572,6 @@ def safe_parse_file(fn):
558572
fn, repr(e)))
559573
return env_data
560574

561-
@classmethod
562-
def safe_parse_json(self, fn):
563-
return self.safe_parse_file(fn+'.json')
564-
565575

566576

567577
@dset(STORES)
@@ -583,8 +593,9 @@ def setitem_callback_setitem(state, key, v):
583593
# def :param data: value to be stored, usually a dict like
584594

585595
class LazyContainerPrototype(Mapping):
586-
# def __init__(self,):
587596
pass
597+
def save_children(self):
598+
return None
588599

589600

590601
def get_led_cls(sel_led, sel_store):
@@ -595,9 +606,7 @@ def get_led_cls(sel_led, sel_store):
595606
# if sel_store == ''
596607
_store = STORES[sel_store]
597608
LEDS = {}
598-
# @dset(LEDS)
599-
# class LazyContainerPrototype(Mapping):
600-
# pass
609+
601610
@dset(LEDS)
602611
class LazyContainerCurrent(LazyContainerPrototype):
603612
# def __init__(self,):
@@ -610,15 +619,11 @@ class LazyContainerCurrent(LazyContainerPrototype):
610619
def __init__(self, tree, schema, value):
611620
self._tree = tree
612621
self.schema = schema
613-
# self._raw_dict = None
614-
# if isinstanceself.schema
615622
v = value
616623
if v is None:
617624
v = {}
618625
elif isinstance(v,LazyContainerPrototype):
619-
# v =
620626
v = v._raw_dict
621-
# v = {k:vv for v}
622627
else:
623628
v = v
624629
self._raw_dict = (v)
@@ -633,41 +638,32 @@ def _pure_setitem(self,k,v):
633638
def _pure_getitem(self,k):
634639
return self._raw_dict.__getitem__(k)
635640

636-
def _pure_get(self,k,v=None):
641+
def _pure_get(self, k, v=None):
637642
return self._raw_dict.get(k,v)
638643

639644
def _pure_items(self):
640645
return self._raw_dict.items()
641-
642646
# def serialize_env_list(self, state, eids, env_path, schema):
643647
# def serialize_env_single(self, state, env_id, env_path, schema):
644-
# '''
645-
# trigger children to save
646-
# '''
647-
# return self.write_key_value_xt( env_path, env_id, state[env_id], schema)
648-
649-
650-
def lazy_load_all_children(self):
648+
def lazy_load_children(self):
651649
'''
652650
Loads all child nodes according to a up-to-date criteria
653651
654652
Only loads windows that are not in state dict
655653
'''
656654
root = {None: self}
657655
env = self.store.lazy_read_file_xt( self.tree, root, None, self.schema)
658-
# import pdb; pdb.set_trace()
659656
self._raw_dict = env._raw_dict
660657
# assert 0
661658
# return env
662-
lazy_load_data = lazy_load_all_children
659+
lazy_load_data = lazy_load_children
663660

664-
def save_all_children(self):
661+
def save_children(self):
665662
'''
666663
save all
667664
'''
668665
# return self.write_key_value_xt( tree, None, self._raw_dict, schema)
669666
return self.store.write_key_value_xt( self.tree, None, self, self.schema)
670-
671667
# return self.store.serialize_env_single( state, eid, env_path, schema = self.schema)
672668

673669
def __getitem__(self, key):
@@ -683,7 +679,7 @@ def __setitem__(self, key, value):
683679
'''
684680
# self.send_data_to_disk(env_path_file, key, value)
685681
self.lazy_load_data()
686-
value = self.store.callback_before_setitem(self,key,value)
682+
value = self.store.callback_before_setitem(self,key,value)
687683
ret = self._raw_dict.__setitem__(key, value)
688684
_ = self.store.callback_after_setitem(self,key,value)
689685
return ret
@@ -697,7 +693,6 @@ def __len__(self):
697693
return len(self._raw_dict)
698694
LazyContainerCurrent.LazyContainerCurrentBase =LazyContainerCurrent
699695

700-
701696
@dset(LEDS)
702697
class LazyEnvData(LazyContainerCurrent):
703698
'''
@@ -713,17 +708,19 @@ def __init__(self, tree):
713708
def serialize_env_list_wschema(self, state, eids, env_path):
714709
'''
715710
Bind schema with Store's method to be used by app
711+
712+
[TBC] needs legacy impl for
713+
- serialize_env_list_wschema()
714+
- lazy_load_data()
716715
'''
717716
eids = [i for i in eids if i in state]
718717
for eid in eids:
719718
# import pdb; pdb.set_trace()
720719
v = state[eid]
721-
v.save_all_children()
720+
v.save_children()
722721
# self.store.serialize_env_single( state, eid, env_path, schema = self.schema)
723722
return eids
724723

725-
726-
727724
return LEDS[sel_led]
728725
# return LazyEnvData
729726

@@ -1471,6 +1468,7 @@ def register_window(self, p, eid):
14711468
is_new_env = True
14721469
self.state[eid] = init_default_env()
14731470

1471+
'## this is the "jsons" container!!! not the env container'
14741472
env = self.state[eid]['jsons']
14751473

14761474
'## allocating window index'
@@ -1484,9 +1482,11 @@ def register_window(self, p, eid):
14841482
'''
14851483
## this is the __setitem__ call.
14861484
Adds per-window caching logic into this call
1485+
1486+
needs to save_children()
14871487
'''
14881488
env[p['id']] = p
1489-
1489+
legacy_save_children(env[p['id']])
14901490

14911491
'## sync window to clients'
14921492
broadcast(self, p, eid)

0 commit comments

Comments
 (0)