<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Wed Feb 07 22:02:28 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[CXX-1389] Provide consistency to write concern</title>
                <link>https://jira.mongodb.org/browse/CXX-1389</link>
                <project id="11980" key="CXX">C++ Driver</project>
                    <description>&lt;p&gt;in the current API. write concern are managed by only one class, beside the fact that several roles has been identified (&lt;a href=&quot;https://docs.mongodb.com/manual/reference/write-concern/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://docs.mongodb.com/manual/reference/write-concern/&lt;/a&gt;)  &lt;/p&gt;

&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;Majority&lt;/li&gt;
	&lt;li&gt;Not Acknowledged&lt;/li&gt;
	&lt;li&gt;Node&lt;/li&gt;
	&lt;li&gt;Tag&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The consequence is that it leads to lack of consistency states for write concern objects.&lt;br/&gt;
Inconsistency managed by the driver. But in this case it&apos;s hard to cover all unexpected configuration. And If it happens, then the user faces an exception followed by a potential core dump.&lt;/p&gt;

&lt;p&gt;Furthermore, the documentation of the API should explicitely provide which state to avoid ...&lt;/p&gt;

&lt;p&gt;All that can be solved by building consistent states. And this can be obtained with a clean classes hierarchy that declare a class for each identified role.&lt;/p&gt;</description>
                <environment></environment>
        <key id="402078">CXX-1389</key>
            <summary>Provide consistency to write concern</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="10038" iconUrl="https://jira.mongodb.org/images/icons/subtask.gif" description="">Backlog</status>
                    <statusCategory id="2" key="new" colorName="default"/>
                                    <resolution id="-1">Unresolved</resolution>
                                        <assignee username="-1">Unassigned</assignee>
                                    <reporter username="yoann.couillec@amadeus.com">Yoann Couillec</reporter>
                        <labels>
                            <label>bg-rf</label>
                            <label>rb-track</label>
                    </labels>
                <created>Mon, 10 Jul 2017 13:50:31 +0000</created>
                <updated>Wed, 7 Feb 2024 11:10:06 +0000</updated>
                                                                            <component>API</component>
                                        <votes>0</votes>
                                    <watches>4</watches>
                                                                                                                <comments>
                            <comment id="1691314" author="yoann.couillec@amadeus.com" created="Fri, 6 Oct 2017 13:14:53 +0000"  >&lt;p&gt;Concerning the idea of immutable write concern, I definitely agree. This keep control of the encapsulated values.&lt;br/&gt;
A class hierarchy for write concerns could be&lt;br/&gt;
 &lt;span class=&quot;image-wrap&quot; style=&quot;&quot;&gt;&lt;a id=&quot;167474_thumb&quot; href=&quot;https://jira.mongodb.org/secure/attachment/167474/167474_write_concern_1.png&quot; title=&quot;write_concern_1.png&quot; file-preview-type=&quot;image&quot; file-preview-id=&quot;167474&quot; file-preview-title=&quot;write_concern_1.png&quot;&gt;&lt;img src=&quot;https://jira.mongodb.org/secure/thumbnail/167474/_thumb_167474.png&quot; style=&quot;border: 0px solid black&quot; role=&quot;presentation&quot;/&gt;&lt;/a&gt;&lt;/span&gt; &lt;/p&gt;</comment>
                            <comment id="1691275" author="yoann.couillec@amadeus.com" created="Fri, 6 Oct 2017 11:56:33 +0000"  >&lt;p&gt;Hello Derick.&lt;/p&gt;

&lt;p&gt;I am glad you ask.&lt;/p&gt;

&lt;h4&gt;&lt;a name=&quot;Generalobservation&quot;&gt;&lt;/a&gt;General observation&lt;/h4&gt;

&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;While coding using cxx driver, I dove into the source code of both C and C++ drivers.&lt;br/&gt;
From that, I saw a weakness in the design of write concerns, which can be generalized to read concerns, read preferences and options.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The main issue is the usage of all-in-one classes. A class that does everything.&lt;/p&gt;

&lt;p&gt;The biggest issue is that it leads to &lt;b&gt;inconsistent&lt;/b&gt; states. &lt;br/&gt;
And the way to get out of them is to check values to be sure being in a safe state.&lt;/p&gt;

&lt;p&gt;But the checks can only be performed at &lt;b&gt;runtime&lt;/b&gt;. &lt;br/&gt;
So if an inconsistent state is detected, either it raises an &lt;b&gt;error&lt;/b&gt;, which is fair.&lt;br/&gt;
Or worse, it will &lt;b&gt;continue&lt;/b&gt;, ignoring the inconsistent state and setting some fields to recover a safe state. As a consequence, the state has been internally modified without awareness of the user.&lt;/p&gt;

&lt;p&gt;The problem can be solved by defining &lt;b&gt;class hierarchies&lt;/b&gt; instead of all-in-one classes&lt;br/&gt;
The main advantage is that inconsistent states are checked at &lt;b&gt;compile-time&lt;/b&gt;.&lt;br/&gt;
Another advantage is that you don&apos;t have to check if the state is safe or not.&lt;/p&gt;

&lt;p&gt;A good demonstration is write concern.&lt;/p&gt;

&lt;h4&gt;&lt;a name=&quot;Writeconcern&quot;&gt;&lt;/a&gt;Write concern&lt;/h4&gt;

&lt;h5&gt;&lt;a name=&quot;The%60w%60fieldofwriteconcerns&quot;&gt;&lt;/a&gt;The ` w` field of write concerns&lt;/h5&gt;

&lt;p&gt;First of all, there are several identified &lt;b&gt;levels&lt;/b&gt; of acknowledgements. However there is just one class/structure representing them all.&lt;br/&gt;
As a consequence, the unique class/structure has to expose all methods/functions concerning all roles and you can set parameters even if it has no sense.&lt;/p&gt;

&lt;p&gt;The identified roles are:&lt;/p&gt;

&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;&lt;b&gt;unacknowledged&lt;/b&gt;. Setting journal to true/false makes sense while setting a timeout does not.&lt;br/&gt;
Then you have an inconsistent state by setting a timeout with a `w` set to 0.&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;tags&lt;/b&gt;. Setting journal and timeout both make sense. but calling the nodes(int) function leads to inconsistent state.&lt;br/&gt;
In that case you have a list of tags but the `w` field contains a number greater than 0.&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;nodes&lt;/b&gt;&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;majority&lt;/b&gt;&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;server&lt;/b&gt; (called default). The design choice for this one, is a bit surprising.&lt;br/&gt;
To say that the server value should be used you have to leave the optional field unset.&lt;br/&gt;
I don&apos;t see any justification in using optional here.&lt;/li&gt;
&lt;/ul&gt;


&lt;h5&gt;&lt;a name=&quot;Specification&quot;&gt;&lt;/a&gt;Specification&lt;/h5&gt;

&lt;p&gt;The specification defines `w` as:&lt;/p&gt;

&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;w: Optional&amp;lt;Int32 | String&amp;gt;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;While `String` concerns both tags write concerns and majority ones.&lt;br/&gt;
Int32 &lt;b&gt;mixes two domains&lt;/b&gt;: the number of the nodes and the types of write concerns.&lt;/p&gt;

&lt;p&gt;So actually, we have here 4 levels of interpretation:&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;the optional one: if it is set, it&apos;s a client write concern, if not, it&apos;s a server write concern&lt;/li&gt;
	&lt;li&gt;when the optional is set: it&apos;s a string or an int&lt;/li&gt;
	&lt;li&gt;when the optional is set and it&apos;s an integer: the int means the number of nodes&lt;/li&gt;
	&lt;li&gt;when the optional is set and it&apos;s a string: tag or majority write concern ...&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Here is the semantics of this field&lt;br/&gt;
 &lt;span class=&quot;image-wrap&quot; style=&quot;&quot;&gt;&lt;a id=&quot;167480_thumb&quot; href=&quot;https://jira.mongodb.org/secure/attachment/167480/167480_semantics.png&quot; title=&quot;semantics.png&quot; file-preview-type=&quot;image&quot; file-preview-id=&quot;167480&quot; file-preview-title=&quot;semantics.png&quot;&gt;&lt;img src=&quot;https://jira.mongodb.org/secure/thumbnail/167480/_thumb_167480.png&quot; style=&quot;border: 0px solid black&quot; role=&quot;presentation&quot;/&gt;&lt;/a&gt;&lt;/span&gt; &lt;/p&gt;

&lt;h5&gt;&lt;a name=&quot;Sourcecodeofmongoc%28xx%29&quot;&gt;&lt;/a&gt;Source code of mongoc(xx)&lt;/h5&gt;
&lt;p&gt;To catch up the inconsistencies, a function has been defined (&lt;a href=&quot;https://github.com/mongodb/mongo-c-driver/blob/master/src/mongoc/mongoc-write-concern.c#L423&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;b&gt;mongoc_write_concern_is_valid&lt;/b&gt;&lt;/a&gt;) with a respectable goal &quot;Checks to see if @write_concern is valid and does not contain conflicting options.&quot;&lt;br/&gt;
Unfortunately, It does not catch all the cases...&lt;/p&gt;

&lt;p&gt;When a &lt;a href=&quot;https://github.com/mongodb/mongo-c-driver/blob/master/src/mongoc/mongoc-write-command.c#L689&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;call&lt;/a&gt; to `mongoc_write_concern_is_valid` is performed, the operation is abandoned and an &lt;a href=&quot;https://github.com/mongodb/mongo-cxx-driver/blob/master/src/mongocxx/collection.cpp#L242&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;exception is raised&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With a &lt;b&gt;class hierarchy&lt;/b&gt;, there is no need to check inconsistency at runtime and no need to raise an exception.&lt;br/&gt;
All is checked at compile-time.&lt;br/&gt;
It&apos;s gain of time for designers and maintainers &lt;img class=&quot;emoticon&quot; src=&quot;https://jira.mongodb.org/images/icons/emoticons/wink.png&quot; height=&quot;16&quot; width=&quot;16&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/p&gt;</comment>
                            <comment id="1684175" author="derick" created="Thu, 28 Sep 2017 13:48:41 +0000"  >&lt;p&gt;HI,&lt;/p&gt;

&lt;p&gt;Sorry for only just getting to this.&lt;/p&gt;

&lt;p&gt;Could you give an example of what can currently go wrong, in your opinion?&lt;/p&gt;

&lt;p&gt;And, how the class hierarchy could work? Right now, the different levels don&apos;t really inherit from each other.&lt;/p&gt;

&lt;p&gt;Do you think that an API as the PHP driver has makes more sense? (See: &lt;a href=&quot;http://php.net/manual/en/mongodb-driver-writeconcern.construct.php&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://php.net/manual/en/mongodb-driver-writeconcern.construct.php&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;cheers,&lt;br/&gt;
Derick&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                            <attachment id="167480" name="semantics.png" size="29286" author="yoann.couillec@amadeus.com" created="Fri, 6 Oct 2017 13:49:56 +0000"/>
                            <attachment id="167474" name="write_concern_1.png" size="27564" author="yoann.couillec@amadeus.com" created="Fri, 6 Oct 2017 13:29:35 +0000"/>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_10857" key="com.pyxis.greenhopper.jira:gh-epic-link">
                        <customfieldname>Epic Link</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>CXX-2825</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hxk88f:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>