{"id":13530736,"url":"https://github.com/pharo-nosql/mongotalk","last_synced_at":"2025-03-23T07:28:51.648Z","repository":{"id":9087164,"uuid":"60769462","full_name":"pharo-nosql/mongotalk","owner":"pharo-nosql","description":"A Pharo driver for MongoDB ","archived":false,"fork":false,"pushed_at":"2024-01-16T12:18:02.000Z","size":758,"stargazers_count":19,"open_issues_count":10,"forks_count":13,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-01-28T14:19:27.833Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Smalltalk","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pharo-nosql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-06-09T11:24:31.000Z","updated_at":"2023-09-20T23:20:56.000Z","dependencies_parsed_at":"2024-01-07T12:51:50.574Z","dependency_job_id":"7b7b220e-b353-43ce-8f14-cf9756a0c353","html_url":"https://github.com/pharo-nosql/mongotalk","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharo-nosql%2Fmongotalk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharo-nosql%2Fmongotalk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharo-nosql%2Fmongotalk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharo-nosql%2Fmongotalk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pharo-nosql","download_url":"https://codeload.github.com/pharo-nosql/mongotalk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245070131,"owners_count":20556061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T07:00:54.309Z","updated_at":"2025-03-23T07:28:51.617Z","avatar_url":"https://github.com/pharo-nosql.png","language":"Smalltalk","funding_links":[],"categories":["Libraries"],"sub_categories":["Smalltalk"],"readme":"# MongoTalk \nA [Pharo](https://www.pharo.org) driver for [MongoDB](https://www.mongodb.com/).\n\n[![CI](https://github.com/pharo-nosql/mongotalk/actions/workflows/tests.yml/badge.svg)](https://github.com/pharo-nosql/mongotalk/actions/workflows/tests.yml)\n[![Coverage Status](https://codecov.io/github/pharo-nosql/mongotalk/coverage.svg?branch=master)](https://codecov.io/gh/pharo-nosql/mongotalk/branch/master)\n\n[![Pharo 10](https://img.shields.io/badge/Pharo-10-%23aac9ff.svg)](https://pharo.org/download)\n[![Pharo 11](https://img.shields.io/badge/Pharo-11-%23aac9ff.svg)](https://pharo.org/download)\n[![Pharo 12](https://img.shields.io/badge/Pharo-12-%23aac9ff.svg)](https://pharo.org/download)\n\n## Getting Started\n\nWe can open a connection to a mongodb server and perform a write operation as follows:\n~~~Smalltalk\nmongo := Mongo host: 'localhost' port: 27017.\nmongo open.\n((mongo\n\tdatabaseNamed: 'test')\n\tgetCollection: 'pilots')\n\tadd: { 'name' -\u003e 'Fangio' } asDictionary.\n~~~\n\n## Install Mongo driver\n\nEvaluate the following script in Pharo:\n```smalltalk\nMetacello new\n\trepository: 'github://pharo-nosql/mongotalk/mc';\n\tbaseline: 'MongoTalk';\n\tload\n```\n\n---\n## Install MongoClient\n\n```smalltalk\nMetacello new\n\trepository: 'github://pharo-nosql/mongotalk/mc';\n\tbaseline: 'MongoTalk';\n\tload: #(Client)\n```\n\n---\n## Older mongo versions (\u003c 5)\nCurrent driver (v5) is incompatible with older mongo versions, if you require to connect to one of those older databases, you will need to first install a legacy driver: \n\n```smalltalk\nMetacello new\n\trepository: 'github://pharo-nosql/mongotalk/mc';\n\tbaseline: 'MongoTalk';\n\tload: #('Mongo-DriverLegacy')\n```\n\nThen you will need to explicitly declare its use in your mongo client: \n```smalltalk\ndb := Mongo new\n\tuseLegacyDriver;\n\topen. \n```\n\nAlternatively, you can also set the default driver to be used in any connection:\n```smalltalk\nMongoDriver defaultDriver: MongoLegacyDriver.\n```\n*This is useful if you are using [Voyage](https://github.com/pharo-nosql/voyage), for example.*\n\n---\n# The MongoDB specification\n\nThe MongoDB core team proposes a [specification](https://github.com/mongodb/specifications) with suggested and required  behavior for drivers (clients).\nAlthough this Pharo driver implements only partially such specification, in next subsections we describe its key elements and link them this Pharo implementation.\n\n## Server Discovery And Monitoring\n\nYou can have an introduction to the [Server Discovery And Monitoring Specification](http://emptysqua.re/server-discovery-and-monitoring.html) in a [blog post](https://www.mongodb.com/blog/post/server-discovery-and-monitoring-next-generation-mongodb-drivers) and in [this talk](https://www.mongodb.com/presentations/mongodb-drivers-and-high-availability-deep-dive).\n\n***Discovery.*** The `MongoClient` receives a *seed list* of URLs when instantiated, which is the initial list of server addresses.\nAfter `#start`, the client starts to *ping* the seed addresses to discover replica set data.\nThis *ping* consists on a [ismaster](https://docs.mongodb.com/v4.0/reference/command/isMaster/) command, which is very light for servers.\n\n***Monitors.*** The spec considers 3 kinds of implementations for monitoring: the single-threaded (Perl), multi-threaded (Python, Java, Ruby, C#), and hybrid (C). The hybrid mixes single and multi.\nOur `MongoClient` has a **multi-threaded approach** to monitor servers.\nMore concretely, it uses [TaskIt](https://github.com/pharo-contributions/taskit) services which relies in `Process` (i.e. [green threads](https://en.wikipedia.org/wiki/Green_threads)).\n\n***States.*** The `MongoClient\u003e\u003eisMonitoringSteadyState` let's you know the internal state of the client, which is one of the following:\n\n* **Crisis state**: It is the initial state: ping each seed address to get the first topology, then move to Steady state. Enqueue incoming commands and ping every 0.5 seconds (not customizable) all known servers until a primary is found. Then, change to Steady state.\n\n* **Steady state**: Ping servers every 10 seconds (by default) to update data, and keep track of latency. When there is a failure, the exception is raised to the application, and it will move to Crisis state.\n\n***Error handling.*** Applications may retry once after a connection failure, and only notify user if this first retry failed too.\nThe explanation is that first failure moves the client to Crisis State, and the retry will have a long Server Selection and hopefully retry after a new primary is elected.\nIt is less likely that a second retry will succeed.\n\n\n## Server Selection\n\nWhen a client receives a write command, there is only one choice: it must be sent to the primary server.\nThe same happens when a client receives a read command with *primary* as read preference.\nInstead, a read operation with another read preference (such as *primaryPreferred*) might have several possible servers to send the command.\nThe [Server Selection specification](https://docs.mongodb.com/manual/core/read-preference-mechanics/) proposes the algorithm for server selection that has the goals of being predictable, resilient, and low-latency.\n[This blog post](https://www.mongodb.com/blog/post/server-selection-next-generation-mongodb-drivers) describes this algorithm in detail:\n\n\u003e Users will be able to control how long server selection is allowed to take with the [serverSelectionTimeoutMS](https://docs.mongodb.com/master/reference/connection-string/) configuration variable and control the size of the acceptable latency window with the localThresholdMS configuration variable.\n\nYou can find our implementation of this algorithm in the `MongoServerSelection` class.\nThe default parameters for the selection is customizable via `localThreshold:`, `readPreference:` and `serverSelectionTimeout:` in the `MongoClientSettings` instance (accessed via `MongoClient\u003e\u003esettings`).\nHowever, several selection parameters may be specialized for each operation with:\n```Smalltalk\nclient\n\tmongoDo: [ :mongo | \"do some operation on the Mongo object here\" ]\n\treadPreference: MongoReadPreference newNearest\n\tlocalThreshold: 100 milliseconds\n```\n\n## Connection Pooling\n\nThe MongoDB specification makes some suggestions and requirements for drivers on this connection pooling characteristics on [this document](https://github.com/mongodb/specifications/blob/master/source/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst).\nYou can find our implementation of this specification in the `MongoPool` class, which is customizable via `connectTimeout:`, `maxConnections:` and `socketTimeout:` in the `MongoClientSettings` instance (accessed via `MongoClient\u003e\u003esettings`).\nWhen the application sends `mongoDo:` to the client, the pool will either reuse a cached `Mongo` instance (that was kept open) or create a new instance.\nWhen the pool opens the socket to the server, it uses a timeout indicated by `connectTimeout`, and then sets the `socketTimeout` which applies to the database and collections read and write commands executed on it by the application.\nPools are initially empty: they grow when `mongoDo:` succeed, and are emptied when a connection error is handled.\nThey only grow up to the quantity indicated by `maxConnections`; when such upper bound is exceeded, the connections are closed when returned by the application.\n\n\n## What's not implemented?\n\nThis is only a partial implementation of the whole MongoDB specification.\n\nFor example, our `MongoClient` doesn't provide any direct read or write operation (as the specification requires).\nInstead, such operations are supported by first obtaining an instance of `Mongo` (the connection to a particular server) and then obtaining the db/collection to perform the operations.\n\nCurrent implementation lacks ReplicaSet support.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpharo-nosql%2Fmongotalk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpharo-nosql%2Fmongotalk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpharo-nosql%2Fmongotalk/lists"}