proxystore.store¶
The ProxyStore Store interface.
Every Store is registered in a
registry that is global to the Python process
and keyed by the unique
id of the store. A store is registered
when it is created and unregistered when it is closed. When a proxy is
resolved, the store which created the proxy is looked up in the registry,
or initialized and registered from the configuration contained in the proxy
if the store does not exist in the process.
Store
¶
Store(
connector: ConnectorT,
*,
name: str | None = None,
serializer: SerializerT | None = None,
deserializer: DeserializerT | None = None,
cache_size_bytes: int = DEFAULT_CACHE_SIZE_BYTES,
cache_mode: CacheModeT = 'objects',
metrics: bool | StoreMetrics = False,
populate_target: bool = True,
owner: bool = True,
_id: str | None = None,
)
Bases: Generic[ConnectorT]
Key-value store interface for proxies.
Tip
A Store instance can be used as a
context manager which will automatically call
close() on exit.
Warning
The default value of populate_target=True can cause unexpected
behavior when the deserializer of the store does not undo its
serializer because neither is applied to the target object cached
in the resulting Proxy.
In this example, the serialized data_bytes was populated as the
target object in the resulting proxy so the proxy looks like a proxy
of bytes rather than the intended list of integers. To fix this, set
populate_target=False so the deserializer is correctly applied to
data_bytes when the proxy is resolved.
Note
This class is thread-safe. Different keys are fetched from the
connector at the same time, and a key that is already being fetched
by another thread is not fetched again. The thread waits for that
fetch instead. The connector must be thread-safe (see
Connector).
Note
Each store has a unique id which
is used to register the store in a registry that is global to the
Python process. The store is registered when initialized and
unregistered when close()
is called. Proxies created by a store contain the configuration of
the store, including the ID, so the store can be found in the
registry, or initialized if needed, when a proxy is resolved.
Warning
This class cannot be pickled. If you need to recreate a
Store within another process, share
a StoreConfig, a serializable
and pickle-compatible type, that can be created using
Store.config().
To reconstruct the instance from the config, use
get_or_create_store(),
which reuses the store if it already exists in the process, or
Store.from_config(),
which always creates a new store instance.
Parameters:
-
connector(ConnectorT) –Connector instance to use for object storage. Keys taken and returned by the store's methods (
KeyT) have the key type of the connector (e.g., aFileKeyfor aFileConnector). -
name(str | None, default:None) –Optional name of the store used in logs and error messages. The name does not need to be unique.
-
serializer(SerializerT | None, default:None) –Optional callable which serializes every object put in the store. If
None, the default serializer (serialize()) will be used. -
deserializer(DeserializerT | None, default:None) –Optional callable which deserializes every object gotten from the store, including when proxies are resolved. If
None, the default deserializer (deserialize()) will be used. The serializer and deserializer are part of theconfig()of the store, so they must be importable in other processes. -
cache_size_bytes(int, default:DEFAULT_CACHE_SIZE_BYTES) –Maximum size of the LRU cache in bytes (256 MiB by default). Each entry counts as the size of the object's serialized data, so with the
'objects'cache mode this is an estimate of the memory used. Objects larger than this are not cached. If 0, the cache is disabled. The cache is local to the Python process. -
cache_mode(CacheModeT, default:'objects') –What the cache holds. With
'objects', the cache holds deserialized objects, so a cache hit is free but everyget()and proxy of a key in this process shares the same object, and changing it changes all of them. With'bytes', the cache holds the serialized data and deserializes it on every hit, so each caller gets its own object at the cost of deserializing each time. -
metrics(bool | StoreMetrics, default:False) –Enable recording operation metrics. Pass a
StoreMetricsinstance to configure it (e.g.,max_keys). The configuration ofStoreMetricsis not part of the store'sconfig(), so stores created from the config in other processes use the defaults. -
populate_target(bool, default:True) –Set the default value of
populate_targetfor proxy methods of the store. -
owner(bool, default:True) –This store owns the objects stored by the connector, so the connector is cleared (e.g., the directory of a
FileConnectoris deleted), according to the connector'sclearsetting, when this store is closed. Stores created implicitly, such as when a proxy is resolved in another process, are never owners.
Raises:
-
ValueError–If
cache_size_bytesis less than zero orcache_modeis not'objects'or'bytes'.
Source code in proxystore/store/base.py
cache
property
¶
cache: LRUCache[ConnectorKeyT, Any]
Cache of objects (or serialized data) in this process.
owner
property
¶
owner: bool
This store owns the objects stored by its connector.
Only the owner clears the connector when closed. See
close().
close
¶
close(*, clear: bool | None = None) -> None
Close the connector associated with the store.
This will (1) close the connector and (2) unregister the store.
If this store is the owner
and the connector removed the stored objects, the ID of the store
stays closed for the rest of the process, so resolving proxies of
the store in this process raises a
StoreClosedError
instead of making a new store.
Warning
This method should only be called at the end of the program when the store will no longer be used, for example once all proxies have been resolved.
Parameters:
-
clear(bool | None, default:None) –Clear the objects stored by the connector (see
Connector.close()). IfNone, the connector's default is used if this store is theownerand the connector is not cleared otherwise.
Source code in proxystore/store/base.py
config
¶
config() -> StoreConfig
Get the store configuration.
Note
The configuration is made when the store is created, and every call returns the same (immutable) object. Changes made to the connector after the store is created are not included.
Returns:
-
StoreConfig–Store configuration.
Source code in proxystore/store/base.py
from_config
classmethod
¶
from_config(
config: StoreConfig, *, owner: bool | None = None
) -> Store[Any]
Create a new store instance from a configuration.
The new store has the same id
as the store which produced the configuration. If config does not
contain an ID (e.g., a configuration loaded from a TOML file),
a new ID is generated.
By default, the new store is the
owner only if config does
not contain an ID. A config with an ID came from an existing store,
and that store is the owner. A config without an ID describes a new
store, so the new store is the owner.
Tip
Use get_or_create_store()
to reuse a store with the same ID that already exists in this
process.
Parameters:
-
config(StoreConfig) –Configuration returned by
.config(). -
owner(bool | None, default:None) –The new store owns the objects stored by the connector. See the
ownerparameter ofStore. IfNone, the new store is the owner only ifconfigdoes not contain an ID.
Returns:
Source code in proxystore/store/base.py
future
¶
future(
*,
evict: bool = False,
polling: PollingPolicy | None = None,
) -> ProxyFuture[T]
Create a future to an object.
Example
from proxystore.connectors.file import FileConnector
from proxystore.store import Store
from proxystore.store.future import ProxyFuture
def remote_foo(future: ProxyFuture) -> None:
# Computation that generates a result value needed by
# the remote_bar function.
future.set_result(...)
def remote_bar(data: Any) -> None:
# Function uses data, which is a proxy, as normal, blocking
# until the remote_foo function has called set_result.
...
with Store(FileConnector(...)) as store:
future = store.future()
# The invoke_remote function invokes a provided function
# on a remote process. For example, this could be a serverless
# function execution.
foo_result_future = invoke_remote(remote_foo, future)
bar_result_future = invoke_remote(remote_bar, future.proxy())
foo_result_future.result()
bar_result_future.result()
Warning
This method only works if the connector is of type
DeferrableConnector.
Parameters:
-
evict(bool, default:False) –If a proxy returned by
ProxyFuture.proxy()should evict the object once resolved. -
polling(PollingPolicy | None, default:None) –Policy for polling the store for the result of the future. If
None, the defaultPollingPolicyis used.
Returns:
-
ProxyFuture[T]–Future which can be used to get the result object at a later time or create a proxy which will resolve to the result of the future.
Raises:
-
NotImplementedError–If the
connectoris not of typeDeferrableConnector.
Source code in proxystore/store/base.py
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 | |
evict
¶
Evict the object associated with the key.
Parameters:
-
key(KeyT) –Key associated with object to evict.
Source code in proxystore/store/base.py
exists
¶
exists(key: KeyT) -> bool
Check if an object associated with the key exists.
Parameters:
-
key(KeyT) –Key potentially associated with stored object.
Returns:
-
bool–If an object associated with the key exists.
Source code in proxystore/store/base.py
get
¶
Get the object associated with the key.
Tip
Like dict.get(), None is returned if the object
does not exist, so a missing object cannot be distinguished from
an object which is None. Use a sentinel default or
exists() if you need
to distinguish the two.
Parameters:
-
key(KeyT) –Key associated with the object to retrieve.
-
default(object | None, default:None) –An optional value to be returned if an object associated with the key does not exist.
Returns:
-
Any | None–Object or
defaultif the object does not exist.
Raises:
-
SerializationError–If an exception is caught when deserializing the object associated with the key.
Source code in proxystore/store/base.py
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | |
get_batch
¶
Get the objects associated with the keys.
Cached objects are returned from the cache, and the remaining objects
are retrieved with a single call to
Connector.get_batch().
Parameters:
-
keys(Sequence[KeyT]) –Sequence of keys associated with the objects to retrieve.
-
default(object | None, default:None) –An optional value to be returned for each object that does not exist.
Returns:
-
list[Any | None]–List with the same order as
keyscontaining each object ordefaultif the object does not exist.
Raises:
-
SerializationError–If an exception is caught when deserializing an object.
Source code in proxystore/store/base.py
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | |
is_cached
¶
is_cached(key: KeyT) -> bool
Check if an object associated with the key is cached locally.
Parameters:
-
key(KeyT) –Key potentially associated with stored object.
Returns:
-
bool–If the object is cached.
Source code in proxystore/store/base.py
proxy
¶
proxy(
obj: T | NonProxiableT,
*,
evict: bool = False,
lifetime: Lifetime | None = None,
populate_target: bool | None = None,
skip_nonproxiable: bool = True,
connector_options: Mapping[str, Any] | None = None,
) -> Proxy[T] | NonProxiableT
Create a proxy that will resolve to an object in the store.
Parameters:
-
obj(T | NonProxiableT) –The object to place in store and return a proxy for.
-
evict(bool, default:False) –If the proxy should evict the object once resolved. Mutually exclusive with the
lifetimeparameter. -
lifetime(Lifetime | None, default:None) –Attach the proxy to this lifetime. The object associated with the proxy will be evicted when the lifetime ends. Mutually exclusive with the
evictparameter. -
populate_target(bool | None, default:None) –Pass
cache_defaults=Trueandtarget=objto theProxyconstructor. I.e., return a proxy that (1) is already resolved, (2) can be used inisinstancechecks without resolving, and (3) is hashable without resolving ifobjis a hashable type. Note that the returned proxy will hold a reference toobjwhich will prevent garbage collectingobj. IfNone, defaults to the store-wide setting. -
skip_nonproxiable(bool, default:True) –Return non-proxiable types (e.g., built-in constants like
boolorNone) directly. IfFalse, aNonProxiableTypeErroris raised instead. -
connector_options(Mapping[str, Any] | None, default:None) –Additional keyword arguments to pass to
Connector.put().
Returns:
-
Proxy[T] | NonProxiableT–A proxy of the object unless
objis a non-proxiable type andskip_nonproxiable is Truein which caseobjis returned directly.
Raises:
-
NonProxiableTypeError–If
objis a non-proxiable type andskip_nonproxiable=False. -
ValueError–If
evictisTrueandlifetimeis notNonebecause these parameters are mutually exclusive.
Source code in proxystore/store/base.py
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 | |
proxy_batch
¶
proxy_batch(
objs: Sequence[T | NonProxiableT],
*,
evict: bool = False,
lifetime: Lifetime | None = None,
populate_target: bool | None = None,
skip_nonproxiable: bool = True,
connector_options: Mapping[str, Any] | None = None,
) -> list[Proxy[T] | NonProxiableT]
Create proxies that will resolve to an object in the store.
Parameters:
-
objs(Sequence[T | NonProxiableT]) –The objects to place in store and return a proxies for.
-
evict(bool, default:False) –If a proxy should evict its object once resolved. Mutually exclusive with the
lifetimeparameter. -
lifetime(Lifetime | None, default:None) –Attach the proxies to this lifetime. The objects associated with each proxy will be evicted when the lifetime ends. Mutually exclusive with the
evictparameter. -
populate_target(bool | None, default:None) –Pass
cache_defaults=Trueandtarget=objto theProxyconstructor. I.e., return a proxy that (1) is already resolved, (2) can be used inisinstancechecks without resolving, and (3) is hashable without resolving ifobjis a hashable type. IfNone, defaults to the store-wide setting. -
skip_nonproxiable(bool, default:True) –Return non-proxiable types (e.g., built-in constants like
boolorNone) directly. IfFalse, aNonProxiableTypeErroris raised instead. -
connector_options(Mapping[str, Any] | None, default:None) –Additional keyword arguments to pass to
Connector.put_batch().
Returns:
-
list[Proxy[T] | NonProxiableT]–A list of proxies of each object or the object itself if said object is not proxiable and
skip_nonproxiable is True.
Raises:
-
NonProxiableTypeError–If
objis a non-proxiable type andskip_nonproxiable=False. -
ValueError–If
evictisTrueandlifetimeis notNonebecause these parameters are mutually exclusive.
Source code in proxystore/store/base.py
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 | |
proxy_from_key
¶
Create a proxy that will resolve to an object already in the store.
Parameters:
-
key(KeyT) –The key associated with an object already in the store.
-
evict(bool, default:False) –If the proxy should evict the object once resolved. Mutually exclusive with the
lifetimeparameter. -
lifetime(Lifetime | None, default:None) –Attach the proxy to this lifetime. The object associated with the proxy will be evicted when the lifetime ends. Mutually exclusive with the
evictparameter.
Returns:
-
Proxy[T]–A proxy of the object.
Raises:
-
ValueError–If
evictisTrueandlifetimeis notNonebecause these parameters are mutually exclusive.
Source code in proxystore/store/base.py
locked_proxy
¶
locked_proxy(
obj: T | NonProxiableT,
*,
evict: bool = False,
lifetime: Lifetime | None = None,
populate_target: bool | None = None,
skip_nonproxiable: bool = True,
connector_options: Mapping[str, Any] | None = None,
) -> ProxyLocker[T] | NonProxiableT
Proxy an object and return ProxyLocker.
Parameters:
-
obj(T | NonProxiableT) –The object to place in store and return a proxy for.
-
evict(bool, default:False) –If the proxy should evict the object once resolved. Mutually exclusive with the
lifetimeparameter. -
lifetime(Lifetime | None, default:None) –Attach the proxy to this lifetime. The object associated with the proxy will be evicted when the lifetime ends. Mutually exclusive with the
evictparameter. -
populate_target(bool | None, default:None) –Pass
cache_defaults=Trueandtarget=objto theProxyconstructor. I.e., return a proxy that (1) is already resolved, (2) can be used inisinstancechecks without resolving, and (3) is hashable without resolving ifobjis a hashable type. IfNone, defaults to the store-wide setting. -
skip_nonproxiable(bool, default:True) –Return non-proxiable types (e.g., built-in constants like
boolorNone) directly. IfFalse, aNonProxiableTypeErroris raised instead. -
connector_options(Mapping[str, Any] | None, default:None) –Additional keyword arguments to pass to
Connector.put().
Returns:
-
ProxyLocker[T] | NonProxiableT–A proxy wrapped in a
ProxyLockerunlessobjis a non-proxiable type andskip_nonproxiable is Truein which caseobjis returned directly.
Raises:
-
NonProxiableTypeError–If
objis a non-proxiable type andskip_nonproxiable=False. -
ValueError–If
evictisTrueandlifetimeis notNonebecause these parameters are mutually exclusive.
Source code in proxystore/store/base.py
owned_proxy
¶
owned_proxy(
obj: T | NonProxiableT,
*,
populate_target: bool | None = None,
skip_nonproxiable: bool = True,
connector_options: Mapping[str, Any] | None = None,
) -> OwnedProxy[T] | NonProxiableT
Create a proxy that will enforce ownership rules over the object.
An OwnedProxy will auto-evict
the object once it goes out of scope. This proxy type can also
be borrowed.
Parameters:
-
obj(T | NonProxiableT) –The object to place in store and return a proxy for.
-
populate_target(bool | None, default:None) –Pass
cache_defaults=Trueandtarget=objto theProxyconstructor. I.e., return a proxy that (1) is already resolved, (2) can be used inisinstancechecks without resolving, and (3) is hashable without resolving ifobjis a hashable type. IfNone, defaults to the store-wide setting. -
skip_nonproxiable(bool, default:True) –Return non-proxiable types (e.g., built-in constants like
boolorNone) directly. IfFalse, aNonProxiableTypeErroris raised instead. -
connector_options(Mapping[str, Any] | None, default:None) –Additional keyword arguments to pass to
Connector.put().
Returns:
-
OwnedProxy[T] | NonProxiableT–A proxy of the object unless
objis a non-proxiable type andskip_nonproxiable is Truein which caseobjis returned directly.
Raises:
-
NonProxiableTypeError–If
objis a non-proxiable type andskip_nonproxiable=False.
Source code in proxystore/store/base.py
put
¶
put(
obj: Any,
*,
lifetime: Lifetime | None = None,
connector_options: Mapping[str, Any] | None = None,
) -> KeyT
Put an object in the store.
Parameters:
-
obj(Any) –Object to put in the store.
-
lifetime(Lifetime | None, default:None) –Attach the key to this lifetime. The object associated with the key will be evicted when the lifetime ends.
-
connector_options(Mapping[str, Any] | None, default:None) –Additional keyword arguments to pass to
Connector.put().
Returns:
-
KeyT–A key which can be used to retrieve the object.
Raises:
-
TypeError–If the output of the serializer is not bytes.
Source code in proxystore/store/base.py
put_batch
¶
put_batch(
objs: Sequence[Any],
*,
lifetime: Lifetime | None = None,
connector_options: Mapping[str, Any] | None = None,
) -> list[KeyT]
Put multiple objects in the store.
Parameters:
-
objs(Sequence[Any]) –Sequence of objects to put in the store.
-
lifetime(Lifetime | None, default:None) –Attach the keys to this lifetime. The objects associated with each key will be evicted when the lifetime ends.
-
connector_options(Mapping[str, Any] | None, default:None) –Additional keyword arguments to pass to
Connector.put_batch().
Returns:
-
list[KeyT]–A list of keys which can be used to retrieve the objects.
Raises:
-
TypeError–If the output of the serializer is not bytes.
Source code in proxystore/store/base.py
1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 | |
StoreConfig
¶
Bases: BaseModel
Store configuration.
Tip
See the Store parameters for more
information about each configuration option.
Attributes:
-
id(str | None) –Unique ID of the store. Stores initialized from configurations with the same ID are considered to be the same store, so a proxy resolved in a process where a store with the same ID exists will use that store. If
None, a new ID is generated when a store is initialized from the configuration. The ID is not included when writing the configuration to a TOML file. -
name(str | None) –Optional store name.
-
connector(ConnectorConfig) –Connector configuration.
-
serializer(SerializerT | None) –Optional serializer.
-
deserializer(DeserializerT | None) –Optional deserializer.
-
cache_size_bytes(int) –Maximum cache size in bytes.
-
cache_mode(CacheModeT) –Cache deserialized objects or serialized data.
-
metrics(bool) –Enable recording operation metrics.
-
populate_target(bool) –Set the default value for the
populate_targetparameter of proxy methods.
from_toml
classmethod
¶
Create a configuration file from a TOML file.
Example
See
write_toml().
Parameters:
Source code in proxystore/store/config.py
write_toml
¶
Write a configuration to a TOML file.
Example
from proxystore.store.config import ConnectorConfig
from proxystore.store.config import StoreConfig
config = StoreConfig(
name='example',
connector=ConnectorConfig(
kind='file',
options={'store_dir': '/tmp/proxystore-cache'},
),
)
config.write_toml('config.toml')
id, and can be loaded
again using StoreConfig.from_toml('config.toml').
Parameters:
Source code in proxystore/store/config.py
StoreFactory
¶
StoreFactory(
key: ConnectorKeyT,
store_config: StoreConfig,
*,
evict: bool = False,
)
Bases: Generic[ConnectorT, T]
Factory that resolves an object from a store.
Adds support for asynchronously retrieving objects from a
Store instance.
The factory takes the store_config parameter that is
used to reinitialize the store if the factory is sent to a remote
process where the store has not already been initialized.
Calls to the factory from threads while another call (or
resolve_async())
is resolving the object wait for that result, so the object is resolved
once and every thread gets the same object.
Parameters:
-
key(ConnectorKeyT) –Key corresponding to object in store.
-
store_config(StoreConfig) –Store configuration used to reinitialize the store if needed.
-
evict(bool, default:False) –If True, evict the object from the store once
resolve()is called.
Source code in proxystore/store/factory.py
get_store
¶
get_store() -> Store[ConnectorT]
Get store and reinitialize if necessary.
Raises:
-
StoreClosedError–If the owner of the store closed it and removed its objects in this process.
Source code in proxystore/store/factory.py
resolve
¶
Get object associated with key from store.
Raises:
-
ProxyResolveMissingKeyError–If the key associated with this factory does not exist in the store.
-
StoreClosedError–If the owner of the store closed it and removed its objects in this process.
Source code in proxystore/store/factory.py
resolve_async
¶
Asynchronously get object associated with key from store.
Nothing happens if the object is already being resolved.
Source code in proxystore/store/factory.py
get_store
¶
Get the store which created a proxy.
The store is initialized and registered from the configuration contained in the proxy's factory if the store does not already exist in this process.
Parameters:
-
proxy(Proxy[T]) –
Returns:
Raises:
-
ProxyStoreFactoryError–If the proxy does not contain a factory of type
StoreFactory. -
StoreClosedError–If the owner of the store closed it and removed its objects in this process.
Source code in proxystore/store/__init__.py
get_or_create_store
¶
get_or_create_store(
store_config: StoreConfig,
) -> Store[Any]
Get a registered store or initialize a new instance from the config.
Note
A new store is not the
owner of the objects stored
by its connector, so closing the store does not clear the connector.
Parameters:
-
store_config(StoreConfig) –Store configuration. If a store with the same
idis registered, that store is returned. Otherwise, a new store is initialized (and registered) from the configuration.
Returns:
Raises:
-
StoreClosedError–If the owner of the store closed it and removed its objects in this process.