<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Wed Feb 07 21:36:33 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>[CSHARP-345] MongoServer.Primary remains null even when there is an active primary.</title>
                <link>https://jira.mongodb.org/browse/CSHARP-345</link>
                <project id="10041" key="CSHARP">C# Driver</project>
                    <description>&lt;p&gt;Test setup:&lt;br/&gt;
Start two mongod instances (plus an arbiter) in a replicaset.&lt;br/&gt;
Connect to the replicaset using the C# Driver.&lt;br/&gt;
Attempting db reads works correctly.&lt;br/&gt;
Shutdown the primary instance, wait for the secondary to be promoted to primary.&lt;br/&gt;
Attempting db reads now fails with a MongoConnectionException (&quot;Unable to choose a server instance.&quot;).&lt;br/&gt;
Note that attempting a db write will temporarily fix the problem until the primary goes down again and a new secondary is promoted.&lt;/p&gt;

&lt;p&gt;The reason is that MongoServer.Primary is null.&lt;/p&gt;

&lt;p&gt;-&lt;del&gt;Sample Code&lt;/del&gt;-&lt;br/&gt;
Create brand new Windows Forms project referencing MongoDB.Driver and MongoDB.Bson, and add the following form files:&lt;br/&gt;
// Form1.Designer.cs&lt;br/&gt;
namespace mongoDriverTest&lt;br/&gt;
{&lt;br/&gt;
	partial class Form1&lt;br/&gt;
	{&lt;br/&gt;
		/// &amp;lt;summary&amp;gt;&lt;br/&gt;
		/// Required designer variable.&lt;br/&gt;
		/// &amp;lt;/summary&amp;gt;&lt;br/&gt;
		private System.ComponentModel.IContainer components = null;&lt;/p&gt;

&lt;p&gt;		/// &amp;lt;summary&amp;gt;&lt;br/&gt;
		/// Clean up any resources being used.&lt;br/&gt;
		/// &amp;lt;/summary&amp;gt;&lt;br/&gt;
		/// &amp;lt;param name=&quot;disposing&quot;&amp;gt;true if managed resources should be disposed; otherwise, false.&amp;lt;/param&amp;gt;&lt;br/&gt;
		protected override void Dispose(bool disposing)&lt;br/&gt;
		{&lt;br/&gt;
			if (disposing &amp;amp;&amp;amp; (components != null))&lt;/p&gt;
			{
				components.Dispose();
			}
&lt;p&gt;			base.Dispose(disposing);&lt;br/&gt;
		}&lt;/p&gt;

&lt;p&gt;		#region Windows Form Designer generated code&lt;/p&gt;

&lt;p&gt;		/// &amp;lt;summary&amp;gt;&lt;br/&gt;
		/// Required method for Designer support - do not modify&lt;br/&gt;
		/// the contents of this method with the code editor.&lt;br/&gt;
		/// &amp;lt;/summary&amp;gt;&lt;br/&gt;
		private void InitializeComponent()&lt;/p&gt;
		{
			this.button1 = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// button1
			// 
			this.button1.Location = new System.Drawing.Point(13, 13);
			this.button1.Name = &quot;button1&quot;;
			this.button1.Size = new System.Drawing.Size(75, 23);
			this.button1.TabIndex = 0;
			this.button1.Text = &quot;button1&quot;;
			this.button1.UseVisualStyleBackColor = true;
			this.button1.Click += new System.EventHandler(this.button1_Click);
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(284, 266);
			this.Controls.Add(this.button1);
			this.Name = &quot;Form1&quot;;
			this.Text = &quot;Form1&quot;;
			this.Load += new System.EventHandler(this.Form1_Load);
			this.ResumeLayout(false);

		}

&lt;p&gt;		#endregion&lt;/p&gt;

&lt;p&gt;		private System.Windows.Forms.Button button1;&lt;br/&gt;
	}&lt;br/&gt;
}&lt;/p&gt;


&lt;p&gt;//&lt;br/&gt;
//&lt;br/&gt;
// Form1.cs&lt;br/&gt;
using System;&lt;br/&gt;
using System.Collections.Generic;&lt;br/&gt;
using System.ComponentModel;&lt;br/&gt;
using System.Data;&lt;br/&gt;
using System.Drawing;&lt;br/&gt;
using System.Linq;&lt;br/&gt;
using System.Text;&lt;br/&gt;
using System.Windows.Forms;&lt;br/&gt;
using MongoDB.Driver;&lt;br/&gt;
using MongoDB.Bson;&lt;/p&gt;

&lt;p&gt;namespace mongoDriverTest&lt;br/&gt;
{&lt;br/&gt;
	public partial class Form1 : Form&lt;br/&gt;
	{&lt;br/&gt;
		MongoServer server;&lt;br/&gt;
		MongoDatabase database;&lt;br/&gt;
		MongoCollection&amp;lt;BsonDocument&amp;gt; books;&lt;br/&gt;
		public Form1()&lt;/p&gt;
		{
			InitializeComponent();
		}

&lt;p&gt;		private void Form1_Load(object sender, EventArgs e)&lt;br/&gt;
		{&lt;br/&gt;
			server = MongoServer.Create(&quot;mongodb://localhost:27021,localhost:27022/?replicaSet=foo;slaveOk=true&quot;);&lt;br/&gt;
			database = server&lt;span class=&quot;error&quot;&gt;&amp;#91;&amp;quot;bar&amp;quot;&amp;#93;&lt;/span&gt;;&lt;br/&gt;
			books = database&lt;span class=&quot;error&quot;&gt;&amp;#91;&amp;quot;books&amp;quot;&amp;#93;&lt;/span&gt;;&lt;br/&gt;
			BsonDocument book = new BsonDocument { &lt;/p&gt;
{ &quot;Author&quot;, &quot;Ernest Hemingway&quot; }, { &quot;Title&quot;, &quot;For Whom The Bell Tolls&quot; } };&lt;br/&gt;
			//SafeModeResult result = books.Insert(book);&lt;br/&gt;
		}&lt;br/&gt;
&lt;br/&gt;
		private void button1_Click(object sender, EventArgs e)&lt;br/&gt;
		{&lt;br/&gt;
			try&lt;br/&gt;
			{&lt;br/&gt;
				BsonDocument bookToInsert = new BsonDocument { { &quot;Author&quot;, &quot;Ernest Hemingway&quot; }
&lt;p&gt;, &lt;/p&gt;
{ &quot;Title&quot;, &quot;For Whom The Bell Tolls&quot; } };&lt;br/&gt;
				//SafeModeResult result = books.Insert(bookToInsert); //If this is line is uncommented, everything works fine.&lt;br/&gt;
				BsonDocument book = books.FindOne();&lt;br/&gt;
				var poo = books.Count();&lt;br/&gt;
				MessageBox.Show(book&lt;span class=&quot;error&quot;&gt;&amp;#91;1&amp;#93;&lt;/span&gt;.ToString());&lt;br/&gt;
			}&lt;br/&gt;
			catch (Exception ex)&lt;br/&gt;
			{
				MessageBox.Show(ex.GetType().ToString() + &quot;::&quot; + ex.Message);
			}&lt;br/&gt;
		}&lt;br/&gt;
	}&lt;br/&gt;
}&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
-&lt;del&gt;Investigation&lt;/del&gt;-&lt;br/&gt;
&lt;br/&gt;
When the primary goes down, the secondary becomes the new primary, but&lt;br/&gt;
the instance&apos;s &quot;State&quot; property never changes from connected, so the&lt;br/&gt;
State property setter&apos;s &quot;if (state != value)&quot; line prevents&lt;br/&gt;
InstanceStateChanged ever getting called on that instance after it&lt;br/&gt;
becomes the new primary.&lt;br/&gt;
It seems that once a write is attempted...&lt;br/&gt;
&lt;br/&gt;
books.Insert(new BsonDocument { { &quot;Author&quot;, &quot;Ernest Hemingway&quot; },{ &quot;Title&quot;, &quot;For Whom The Bell Tolls&quot; }
&lt;p&gt; });&lt;/p&gt;

&lt;p&gt;...the below call stack happens...&lt;/p&gt;

&lt;p&gt;MongoDB.Driver.MongoServer.InstanceStateChanged(object sender =&lt;/p&gt;
{MongoDB.Driver.MongoServerInstance}
&lt;p&gt;, object args = null)&lt;br/&gt;
MongoDB.Driver.MongoServerInstance.State.set(MongoDB.Driver.MongoServerState&lt;br/&gt;
value = Connected)&lt;br/&gt;
MongoDB.Driver.MongoServerInstance.VerifyState(MongoDB.Driver.Internal.MongoConnection&lt;br/&gt;
connection = &lt;/p&gt;
{MongoDB.Driver.Internal.MongoConnection}
&lt;p&gt;)&lt;br/&gt;
MongoDB.Driver.MongoServerInstance.Connect(bool slaveOk = true)&lt;br/&gt;
MongoDB.Driver.Internal.ReplicaSetConnector.ConnectWorkItem(object&lt;br/&gt;
argsObject =&lt;/p&gt;
{MongoDB.Driver.Internal.ReplicaSetConnector.ConnectArgs}
&lt;p&gt;)&lt;br/&gt;
&lt;span class=&quot;error&quot;&gt;&amp;#91;External Code&amp;#93;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;...which flips the instance&apos;s state from connected to connecting (and&lt;br/&gt;
eventually back again to connected), causing Instances.Primary to be&lt;br/&gt;
set to this new primary instance, however, this call stack ONLY&lt;br/&gt;
happens when a write is attempted. If I just continue attempting to&lt;br/&gt;
read (since SlaveOk is true), the state remains &quot;Connected&quot;&lt;br/&gt;
indefinitely, and no new Primary gets set. &lt;/p&gt;


&lt;p&gt;This may have been difficult to catch, because if there are&lt;br/&gt;
multiple secondaries when the primary goes down, one of them will&lt;br/&gt;
become the next primary and, although MongServer.Primary will continue&lt;br/&gt;
to be null, the following part of MongServer.ChooseServerInstance(bool&lt;br/&gt;
slaveOk) will ensure that reads continue to work fine against one of&lt;br/&gt;
the other secondaries...&lt;br/&gt;
if (instance.State == MongoServerState.Connected &amp;amp;&amp;amp;&lt;br/&gt;
(instance.IsSecondary || instance.IsPassive)) {&lt;br/&gt;
return instance; &lt;/p&gt;</description>
                <environment></environment>
        <key id="23993">CSHARP-345</key>
            <summary>MongoServer.Primary remains null even when there is an active primary.</summary>
                <type id="1" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14703&amp;avatarType=issuetype">Bug</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="9">Done</resolution>
                                        <assignee username="robert@mongodb.com">Robert Stam</assignee>
                                    <reporter username="mcassidy">Mo Cassidy</reporter>
                        <labels>
                    </labels>
                <created>Mon, 24 Oct 2011 17:07:32 +0000</created>
                <updated>Thu, 2 Apr 2015 18:27:42 +0000</updated>
                            <resolved>Fri, 4 Nov 2011 14:43:54 +0000</resolved>
                                    <version>1.3</version>
                                    <fixVersion>1.3.1</fixVersion>
                                                        <votes>0</votes>
                                    <watches>1</watches>
                                                                                                                <comments>
                            <comment id="64718" author="rstam" created="Fri, 4 Nov 2011 14:43:54 +0000"  >&lt;p&gt;Resolved by making sure StateChanged event is raised when any of the state related properties (State, IsPrimary, IsSecondary, IsPassive and IsArbiter) changes value, not just when State changes value.&lt;/p&gt;</comment>
                            <comment id="62248" author="mcassidy" created="Mon, 24 Oct 2011 17:10:51 +0000"  >&lt;p&gt;Original google groups thread at: &lt;a href=&quot;http://groups.google.com/group/mongodb-csharp/browse_thread/thread/3e11574e2f2a8f08&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://groups.google.com/group/mongodb-csharp/browse_thread/thread/3e11574e2f2a8f08&lt;/a&gt;&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                        <customfield id="customfield_10011" key="com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons">
                        <customfieldname>Backwards Compatibility</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10038"><![CDATA[Fully Compatible]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hrh89r:</customfieldvalue>

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