shareddata 6.85.2__tar.gz → 6.85.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. {shareddata-6.85.2/src/shareddata.egg-info → shareddata-6.85.3}/PKG-INFO +1 -1
  2. {shareddata-6.85.2 → shareddata-6.85.3}/setup.py +1 -1
  3. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Table.py +13 -7
  4. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableDisk.py +66 -4
  5. {shareddata-6.85.2 → shareddata-6.85.3/src/shareddata.egg-info}/PKG-INFO +1 -1
  6. {shareddata-6.85.2 → shareddata-6.85.3}/LICENSE +0 -0
  7. {shareddata-6.85.2 → shareddata-6.85.3}/MANIFEST.in +0 -0
  8. {shareddata-6.85.2 → shareddata-6.85.3}/README.md +0 -0
  9. {shareddata-6.85.2 → shareddata-6.85.3}/pyproject.toml +0 -0
  10. {shareddata-6.85.2 → shareddata-6.85.3}/setup.cfg +0 -0
  11. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/ServerGunicorn.py +0 -0
  12. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/ServerWaitress.py +0 -0
  13. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/__init__.py +0 -0
  14. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/apidocs-dark.css +0 -0
  15. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/apidocs.yml +0 -0
  16. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/auth.py +0 -0
  17. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/constants.py +0 -0
  18. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/download_paths.py +0 -0
  19. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/download_slots.py +0 -0
  20. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/install/worker.ps1 +0 -0
  21. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/install/worker.sh +0 -0
  22. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/listcache.py +0 -0
  23. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/__init__.py +0 -0
  24. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/cache.py +0 -0
  25. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/collections.py +0 -0
  26. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/data.py +0 -0
  27. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/downloads.py +0 -0
  28. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/metadata.py +0 -0
  29. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/operations.py +0 -0
  30. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/schedules.py +0 -0
  31. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/sqlite.py +0 -0
  32. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/system.py +0 -0
  33. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/tables.py +0 -0
  34. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/timeseries.py +0 -0
  35. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/web_routes.py +0 -0
  36. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/routes/workers.py +0 -0
  37. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/API/utils.py +0 -0
  38. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Auth/__init__.py +0 -0
  39. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Auth/bootstrap.py +0 -0
  40. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Auth/migrate.py +0 -0
  41. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Auth/store.py +0 -0
  42. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Auth/workers.py +0 -0
  43. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/CacheRedis.py +0 -0
  44. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/CollectionMongoDB.py +0 -0
  45. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/DataAPI/__init__.py +0 -0
  46. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/DataAPI/catalog.py +0 -0
  47. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/DataAPI/config.py +0 -0
  48. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/DataAPI/errors.py +0 -0
  49. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/DataAPI/indexes.py +0 -0
  50. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/DataAPI/readers.py +0 -0
  51. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/DataAPI/resolve.py +0 -0
  52. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/DataAPI/service.py +0 -0
  53. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Database.py +0 -0
  54. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Defaults.py +0 -0
  55. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/AWSEC2.py +0 -0
  56. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/AWSS3.py +0 -0
  57. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/AutoDocstrings.py +0 -0
  58. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/ClientAPI.py +0 -0
  59. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/ClientSocket.py +0 -0
  60. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/ClientWebSocket.py +0 -0
  61. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/LogHandlerAPI.py +0 -0
  62. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/LogReader.py +0 -0
  63. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/MongoDBClient.py +0 -0
  64. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/SaveTables.py +0 -0
  65. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/ServerSocket.py +0 -0
  66. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/ServerWebSocket.py +0 -0
  67. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/StreamsCache.py +0 -0
  68. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/StreamsPersist.py +0 -0
  69. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/SyncTable.py +0 -0
  70. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/TunnelWebSocket.py +0 -0
  71. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/IO/__init__.py +0 -0
  72. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Listing.py +0 -0
  73. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/LockWaiters.py +0 -0
  74. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Logger.py +0 -0
  75. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/MCP/__init__.py +0 -0
  76. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/MCP/__main__.py +0 -0
  77. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/MCP/client.py +0 -0
  78. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/MCP/server.py +0 -0
  79. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Metadata.py +0 -0
  80. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/MultiProc.py +0 -0
  81. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/OpenFIGI.py +0 -0
  82. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Redaction.py +0 -0
  83. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/ArchiveOldCollections.py +0 -0
  84. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/BatchJob.py +0 -0
  85. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/ContainerHealth.py +0 -0
  86. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/JobStore.py +0 -0
  87. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/RoutineCommand.py +0 -0
  88. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/RoutineOrigin.py +0 -0
  89. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/Schedule.py +0 -0
  90. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/ScheduleMirror.py +0 -0
  91. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/ScheduleMonitor.py +0 -0
  92. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/ScheduleStore.py +0 -0
  93. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/Scheduler.py +0 -0
  94. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/UpdateActiveJobs.py +0 -0
  95. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/Worker.py +0 -0
  96. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/WorkerBootstrap.py +0 -0
  97. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/WorkerLib.py +0 -0
  98. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/WorkerPool.py +0 -0
  99. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Routines/__init__.py +0 -0
  100. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/SQLite.py +0 -0
  101. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/SharedData.py +0 -0
  102. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/SharedNumpy.py +0 -0
  103. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/StreamKafka.py +0 -0
  104. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Symbol.py +0 -0
  105. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableIndex.py +0 -0
  106. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableIndexJitFunctions.py +0 -0
  107. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableIndexJitFunctionsManual.py +0 -0
  108. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableIndexJitGenerate.py +0 -0
  109. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableIndexJitHash.py +0 -0
  110. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableIndexJitLoc.py +0 -0
  111. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableProtocol.py +0 -0
  112. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableRead.py +0 -0
  113. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TableRewrite.py +0 -0
  114. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TimeSeriesDisk.py +0 -0
  115. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/TimeseriesContainer.py +0 -0
  116. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Users.py +0 -0
  117. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Utils.py +0 -0
  118. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/ADDING_A_PAGE.md +0 -0
  119. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/__init__.py +0 -0
  120. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/activity_logger.py +0 -0
  121. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/app.py +0 -0
  122. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/assets/dashAgGridComponentFunctions.js +0 -0
  123. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/assets/dashAgGridFunctions.js +0 -0
  124. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/assets/google_logo.png +0 -0
  125. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/assets/kafka_keys.js +0 -0
  126. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/assets/logs.css +0 -0
  127. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/assets/sched.css +0 -0
  128. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/assets/styles.css +0 -0
  129. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/auth.py +0 -0
  130. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/backends.py +0 -0
  131. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/config.py +0 -0
  132. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/containers.py +0 -0
  133. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/identity.py +0 -0
  134. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/kafka_view.py +0 -0
  135. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/mongo_view.py +0 -0
  136. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/proc.py +0 -0
  137. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/redis_view.py +0 -0
  138. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/route_health.py +0 -0
  139. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/route_registry.py +0 -0
  140. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/sched.py +0 -0
  141. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/schedule_editor.py +0 -0
  142. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/server.py +0 -0
  143. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/services.py +0 -0
  144. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/shell.py +0 -0
  145. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/standalone.py +0 -0
  146. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/account.js +0 -0
  147. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/custom.css +0 -0
  148. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/favicon.ico +0 -0
  149. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/favicon.png +0 -0
  150. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/logo.png +0 -0
  151. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/logo_96x96.png +0 -0
  152. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/shareddata-mark.svg +0 -0
  153. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/shell.css +0 -0
  154. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/shell.js +0 -0
  155. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/standalone.css +0 -0
  156. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/static/standalone.js +0 -0
  157. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/suggest.py +0 -0
  158. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/account.html +0 -0
  159. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/base.html +0 -0
  160. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/claim.html +0 -0
  161. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/claim_done.html +0 -0
  162. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/dash.html +0 -0
  163. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/index.html +0 -0
  164. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/login.html +0 -0
  165. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/login_2fa.html +0 -0
  166. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/partials/navbar.html +0 -0
  167. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/partials/scripts.html +0 -0
  168. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/recovery_codes.html +0 -0
  169. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/shell.html +0 -0
  170. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/templates/standalone.html +0 -0
  171. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/twofactor.py +0 -0
  172. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/utils.py +0 -0
  173. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/Web/workerpool.py +0 -0
  174. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/__init__.py +0 -0
  175. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/build_info.py +0 -0
  176. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/fleet.py +0 -0
  177. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/preflight.py +0 -0
  178. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/private_files.py +0 -0
  179. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/release_backup.py +0 -0
  180. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/server.py +0 -0
  181. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/services.py +0 -0
  182. {shareddata-6.85.2 → shareddata-6.85.3}/src/SharedData/sharedmutexwin.pyd +0 -0
  183. {shareddata-6.85.2 → shareddata-6.85.3}/src/shareddata.egg-info/SOURCES.txt +0 -0
  184. {shareddata-6.85.2 → shareddata-6.85.3}/src/shareddata.egg-info/dependency_links.txt +0 -0
  185. {shareddata-6.85.2 → shareddata-6.85.3}/src/shareddata.egg-info/entry_points.txt +0 -0
  186. {shareddata-6.85.2 → shareddata-6.85.3}/src/shareddata.egg-info/requires.txt +0 -0
  187. {shareddata-6.85.2 → shareddata-6.85.3}/src/shareddata.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shareddata
3
- Version: 6.85.2
3
+ Version: 6.85.3
4
4
  Summary: Memory Mapped / Shared Memory Database with S3 repository
5
5
  Home-page: https://shareddata.net
6
6
  Author: shareddata
@@ -66,7 +66,7 @@ test_requires = [
66
66
 
67
67
  setup(
68
68
  name='shareddata',
69
- version='6.85.2',
69
+ version='6.85.3',
70
70
  description='Memory Mapped / Shared Memory Database with S3 repository',
71
71
  author='shareddata',
72
72
  author_email='admin@shareddata.net',
@@ -865,20 +865,26 @@ class Table:
865
865
  raise RewriteError('automatic disk header migration requires staged publication')
866
866
 
867
867
  ############### DOWNLOAD ###############
868
- def _remote_is_newer(self):
869
- """True when the remote head or tail is newer than this table's (what S3Download would
870
- fetch). Nothing newer, no remote copy, or S3 switched off: False, and the local image stays."""
868
+ def _remote_change(self):
869
+ """What a reload would have to fetch: 'head' when the remote head is newer than this table's
870
+ (the whole image changed), 'tail' when only the remote tail is (the usual case: the rows of
871
+ the current year), None when nothing is newer, there is no remote copy, or S3 is off."""
871
872
  from SharedData.services import s3_enabled
872
873
  if not s3_enabled() or self.hdr is None:
873
- return False
874
+ return None
874
875
  head = S3GetMtime(str(self.headpath) + '.gzip', self.database_folder)
875
876
  if head is not None and head > float(self.hdr['mtimehead']):
876
- return True
877
+ return 'head'
877
878
  if int(self.hdr['hastail']) == 1:
878
879
  tail = S3GetMtime(str(self.tailpath) + '.gzip', self.database_folder)
879
880
  if tail is not None and tail > float(self.hdr['mtimetail']):
880
- return True
881
- return False
881
+ return 'tail'
882
+ return None
883
+
884
+ def _download_remote_tail(self):
885
+ """[io, local mtime, remote mtime] of the remote tail; io is None unless it is newer than this table's."""
886
+ return S3Download(str(self.tailpath) + '.gzip', local_mtime=float(self.hdr['mtimetail']),
887
+ database_folder=self.database_folder)
882
888
 
883
889
  @structural
884
890
  def download(self):
@@ -266,9 +266,11 @@ class TableDisk(Table):
266
266
  Replace the local image with the remote copy when that is newer.
267
267
 
268
268
  Nothing newer remotely (or no remote copy, or S3 off) leaves the local table as it is, so
269
- rows not uploaded yet are never discarded. Otherwise the whole remote image is built beside
270
- data.bin under a stage name and installed by one os.replace, inside the caller's STRUCT
271
- section: a failure before the replace leaves the old image untouched, and the epoch
269
+ rows not uploaded yet are never discarded. When only the remote tail is newer (the usual
270
+ case: the head holds the years before this one and the tail this year's rows) only the tail
271
+ is fetched and applied, see _reload_tail. When the remote head is newer, the whole remote
272
+ image is built beside data.bin under a stage name and installed by one os.replace, inside
273
+ the caller's STRUCT section: a failure before the replace leaves the old image untouched, and the epoch
272
274
  published on leaving the section makes other processes reopen the new file. The old index
273
275
  files describe the old rows, so they are removed and rebuilt.
274
276
 
@@ -278,8 +280,11 @@ class TableDisk(Table):
278
280
  import stat
279
281
  import uuid
280
282
  from SharedData.TableRewrite import fsync_directory, read_layout, require_rewrite_support, sync_file
281
- if not self._remote_is_newer():
283
+ change = self._remote_change()
284
+ if change is None:
282
285
  return self.records
286
+ if change == 'tail' and not self.is_schemaless:
287
+ return self._reload_tail()
283
288
  require_rewrite_support()
284
289
  final = self.filepath
285
290
  old = os.stat(final)
@@ -334,6 +339,63 @@ class TableDisk(Table):
334
339
  raise Exception(errmsg)
335
340
  return self.records
336
341
 
342
+ def _reload_tail(self):
343
+ """
344
+ Apply the remote tail alone: its cost is the tail, not the table (that is what the head/tail
345
+ split is for). Runs inside reload's STRUCT section, with the writer lock held.
346
+
347
+ The tail rows are written into the live file right after the head, the file is synced, and
348
+ the header (count, tail size and time) is committed last. A process that dies before the
349
+ commit leaves the old header: the old tail time is still older than the remote one, so the
350
+ next reload applies the tail again, and the index is rebuilt from the committed rows (the
351
+ dead holder leaves the table flagged DIRTY). No reader looks at the file meanwhile: STRUCT
352
+ keeps lock-free readers waiting and the other readers take the same lock.
353
+ """
354
+ from SharedData.TableRewrite import sync_file
355
+ tail_gz, _, remote_mtime = self._download_remote_tail()
356
+ if tail_gz is None: # nothing newer after all
357
+ return self.records
358
+ live, size = self.hdr, self.size
359
+ self.hdr = live.copy() # the mapped header stays as it was until the commit
360
+ self._bootstrap_record_download = True # reload holds the lock: the tail may be written into the live file
361
+ try:
362
+ tail_gz.seek(0) # S3Download leaves the buffer at its end
363
+ tail_io = gzip.GzipFile(fileobj=tail_gz, mode='rb')
364
+ self.read_tailheader(tail_io) # count, tail size and tail time of the new header
365
+ self.hdr['mtimetail'] = remote_mtime
366
+ if int(self.hdr['count']) > int(self.hdr['recordssize']):
367
+ self.hdr['recordssize'] = self.hdr['count']
368
+ if self.size is None or self.size < int(self.hdr['recordssize']):
369
+ self.size = int(self.hdr['recordssize'])
370
+ self.create_file() # a table that grew gets a longer file: never shortened or rewritten
371
+ self.read_tail(tail_io)
372
+ sync_file(self.filepath)
373
+ self.hdr['isloaded'] = 0
374
+ self.hdr['isidxcreated'] = 0
375
+ committed = self.hdr
376
+ except BaseException:
377
+ self.hdr, self.size = live, size
378
+ raise
379
+ finally:
380
+ self._bootstrap_record_download = False
381
+ self.shf_hdr[0] = committed # the commit
382
+ self.shf_hdr.flush()
383
+ sync_file(self.filepath)
384
+ try:
385
+ self.free(acquire=False)
386
+ self.malloc()
387
+ if self.hasindex:
388
+ self.hdr['isidxcreated'] = 0
389
+ self.index.initialize()
390
+ self.shareddata.data[self.relpath] = self
391
+ self.hdr['isloaded'] = 1
392
+ self.mutex['isloaded'] = 1
393
+ except Exception as e:
394
+ errmsg = f"TableDisk.reload() {self.relpath}: {e}"
395
+ Logger.log.error(errmsg)
396
+ raise Exception(errmsg)
397
+ return self.records
398
+
337
399
  ############### DELETE ###############
338
400
  def delete_local(self):
339
401
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shareddata
3
- Version: 6.85.2
3
+ Version: 6.85.3
4
4
  Summary: Memory Mapped / Shared Memory Database with S3 repository
5
5
  Home-page: https://shareddata.net
6
6
  Author: shareddata
File without changes
File without changes
File without changes
File without changes
File without changes