Repository: internetarchive/openlibrary

Issue:
Open Library Stats Cron hitting Document update conflict
<!-- What problem are we solving? What does the experience look like today? What are the symptoms? -->

```
Traceback (most recent call last):
  File "/openlibrary/scripts/store_counts.py", line 18, in <module>
    sys.exit(stats.main(*sys.argv[1:]))
  File "/openlibrary/openlibrary/admin/stats.py", line 168, in main
    store_data(data, today.strftime("%Y-%m-%d"))
  File "/openlibrary/openlibrary/admin/stats.py", line 68, in store_data
    web.ctx.site.store[uid] = doc
  File "/openlibrary/infogami/infobase/client.py", line 630, in __setitem__
    return self._request(key, method='PUT', data=json.dumps(data))
  File "/openlibrary/infogami/infobase/client.py", line 569, in _request
    out = self.conn.request(self.name, "/_store/" + path, method, data)
  File "/openlibrary/openlibrary/plugins/openlibrary/connection.py", line 54, in request
    return self.store_put(sitename, path, data)
  File "/openlibrary/openlibrary/plugins/openlibrary/connection.py", line 101, in store_put
    return self.conn.request(sitename, path, 'PUT', data)
  File "/openlibrary/openlibrary/plugins/openlibrary/connection.py", line 54, in request
    return self.store_put(sitename, path, data)
  File "/openlibrary/openlibrary/plugins/openlibrary/connection.py", line 101, in store_put
    return self.conn.request(sitename, path, 'PUT', data)
  File "/openlibrary/openlibrary/plugins/openlibrary/connection.py", line 54, in request
    return self.store_put(sitename, path, data)
  File "/openlibrary/openlibrary/plugins/openlibrary/connection.py", line 392, in store_put
    result = ConnectionMiddleware.store_put(self, sitename, path, data)
  File "/openlibrary/openlibrary/plugins/openlibrary/connection.py", line 101, in store_put
    return self.conn.request(sitename, path, 'PUT', data)
  File "/openlibrary/openlibrary/plugins/openlibrary/connection.py", line 570, in request
    return self.writer.request(sitename, path, method, data=data)
  File "/openlibrary/infogami/infobase/client.py", line 197, in request
    self.handle_error(
  File "/openlibrary/infogami/infobase/client.py", line 91, in handle_error
    raise ClientException(status, message, json_data)
infogami.infobase.client.ClientException: Document update conflict
```

### Evidence / Screenshot (if possible)

### Relevant url?
<!-- `https://openlibrary.org/...` -->

### Steps to Reproduce
<!-- What steps caused you to find the bug? -->
1. Go to ...
2. Do ...

<!-- What actually happened after these steps? What did you expect to happen? -->
* Actual:
* Expected:

### Details

- **Logged in (Y/N)?**
- **Browser type/version?**
- **Operating system?**
- **Environment (prod/dev/local)?** prod
<!-- If not sure, put prod -->

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

### Related files
<!-- Files related to this issue; this is super useful for new contributors who might want to help! If you're not sure, leave this blank; a maintainer will add them. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->



Discussion:
Still looks a little funky; but works correctly when we backfill it by running it manually for 30 days.
we needed to add `doc["_rev"] = None` to line 67 on `/openlibrary/openlibrary/admin/stats.py` to avoid the revision from conflicting between scripts.

Resolving patch:
diff --git a/openlibrary/admin/stats.py b/openlibrary/admin/stats.py
--- a/openlibrary/admin/stats.py
+++ b/openlibrary/admin/stats.py
@@ -65,6 +65,9 @@ def store_data(data, date):
     doc = web.ctx.site.store.get(uid) or {}
     doc.update(data)
     doc['type'] = 'admin-stats'
+    # as per https://github.com/internetarchive/infogami/blob/master/infogami/infobase/_dbstore/store.py#L79-L83
+    # avoid document collisions if multiple tasks updating stats in competition (race)
+    doc["_rev"] = None
     web.ctx.site.store[uid] = doc
 
 


Test patch: