-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: sqlite3.OperationalError: table embeddings_queue already exists #1209
Comments
It is recommended to use a single client https://docs.trychroma.com/usage-guide as mentioned under "Use a single-client at a time". A single client is thread-safe. Could you amend your design so that the client is shared between threads? We should add better error messaging here. |
That makes it more difficult to use or design, because then an additional global state has to be maintained for each such database that multiple users would access. It would be better if chroma handled this itself, especially as it fails under this situation. Why make the user of chroma manage the client state when chroma could do it? |
We are actively working on the concept of "Database" as a namespace. I am not sure what your application logic is, but if you share more context perhaps I can suggest an interim workaround. |
Hi, the project is https://github.com/h2oai/h2ogpt . Chroma is key and central to the project. I moved 2 weeks ago to latest chroma, and handled migration directly within h2oGPT so old databases use old chroma by default, since migration is slow. As for h2oGPT, the design is as follows:
|
I see, could collection-level namespacing work for you if we allow'ed something like client.get_collection(where={collection_metadata_you_filter_on: "id"}? Let me also do some digging if we can unblock this specific way of working. It basically amounts to making that migration idempotent if there aren't any other logical issues. |
@HammadB, maybe we can serialise access at SegmentAPI level? @pseudotensor, is it safe to assume that Gradio uses threading as opposed to sub-process for your workload? |
@pseudotensor, try pulling and running your tests against this - https://github.com/amikos-tech/chroma-core/tree/feature/local-client-thread-safety I used the following to test multithreading with PersistentClients import random
import threading
from time import sleep
import chromadb
import shutil
# Delete the database if it exists
try:
shutil.rmtree("chroma-test")
except:
pass
def worker():
client = chromadb.PersistentClient(path="chroma-test")
client.heartbeat()
sleep(random.randint(1,10))
client.get_or_create_collection("test")
sleep(random.randint(1, 10))
try:
client.delete_collection("test")
except ValueError:
pass
# Creating threads
thread1 = threading.Thread(target=worker)
thread2 = threading.Thread(target=worker)
thread3 = threading.Thread(target=worker)
thread4 = threading.Thread(target=worker)
# Starting threads
thread1.start()
thread2.start()
thread3.start()
thread4.start()
# Wait for both threads to complete
thread1.join()
thread2.join()
thread3.join()
thread4.join() |
The client is thread safe - that is different than having multiple clients. |
Hi, Yes gradio uses asyncio and I launch threads to manage access multiple models connected to distant inference servers. So at any one time the chroma package may be asked to access any number of databases by any number of threads per database. |
I think you are recommending a client per user perhaps? But even then, a single user might access (via asyncio leading into threads) multiple databases. So it is possible to create a client for every one case, but it feels like something chroma should manage. That is, if I have a database object from langchain, it seems that object itself should be thread safe, not just some particular client instance that langchain does not directly give users access to. |
@pseudotensor, we dug a little deeper on this to fully understand it, as the PR I hastily raised was a heavy-handed serialization which is a bit blunt. The bottom line is if you have a setup like this: You should be fine with the change we plan. EDIT: Worth asking whether you keep references to the user's Chroma Persistent Client across the user session, which may comprise multiple requests. |
…tp clients (#1270) ## Description of changes *Summarize the changes made by this PR.* - Improvements & Bug fixes - Removed mutable default settings and headers, as this seems ## Test plan *How are these changes tested?* - [x] Tests pass locally with `pytest` for python ## Documentation Changes N/A This issue partly resolves - #1209 (for multiple local persistent clients with different persist paths)
@pseudotensor We just shipped #1244 - which removes the restriction on multiple clients and also introduced tenant/database abstractions. I think this should help with your use case. |
@HammadB Thanks! I'll review and see if I understand the changes and how it helps |
Closing this as stale - as the underlying issue - multiple persistent clients is solved /supported now. |
What happened?
Versions
chromadb==0.4.10
Relevant log output
Is it not allowed to have multiple clients access in different threads the same database?
The text was updated successfully, but these errors were encountered: