类:Mongo::Retryable::WriteWorker Private

继承:
BaseWorker 显示全部
定义于:
lib/ Mongo/retryable/write_worker.rb

Overview

此类是私有 API 的一部分。 应尽可能避免使用此类,因为它将来可能会被删除或更改。

实现有关重试写入操作的逻辑。

由于:

  • 2.19.0

实例属性摘要

BaseWorker继承的属性

#retryable

实例方法摘要折叠

BaseWorker继承的方法

#initialize

构造函数详情

该类从Mongo::Retryable::BaseWorker继承了一个构造函数

实例方法详细信息

# nro_write_with_retry (_write_concern, context:) {|connection, txn_num, context|... } ⇒ 对象

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

可重试写入包装器,适用于不支持现代可重试写入的操作。

如果驱动程序配置为使用现代可重试写入,则此方法只会让出传递的区块一次,因此不会重试任何写入。

如果驱动程序配置为使用旧版可重试写入,则此方法将委托给使用旧版逻辑执行写入重试的legacy_write_with_retry。

参数:

  • write_concern ( nil | Hash | WriteConcern::Base )

    写关注(write concern)。

  • 上下文 ( Context )

    操作的上下文。

收益参数:

  • 连接 (连接)

    应通过其发送写入的连接。

  • txn_num ( nil )

    nil 作为ACID 事务编号。

  • 上下文 ( Operation::Context )

    操作上下文。

由于:

  • 2.19.0



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/ Mongo/retryable/write_worker.rb', line 105

def nro_write_with_retry(写入, 上下文:, )
  会话 = 上下文.会话
  server = select_server(集群, ServerSelector.主节点, 会话)
  选项 = 会话&。客户端&。选项 || {}

  if 选项[:retry_writes]
    error_count = 0
    error_to_rise = nil
    开始
      server.with_connection(connection_global_id: 上下文.connection_global_id) do |连接|
        产量 连接, nil, 上下文
      end
    救援 错误::超时错误
      提高
    救援 *retryable_exceptions, 错误::PoolError, 错误::OperationFailure::家庭情况 => e
      if retryable_overload_error?(e)
        error_count += 1
        error_to_rise ||= e
        除非 e.respond_to?(:label?) && e.标签?('NoWritesPerformed')
          error_to_rise = e
        end
        延迟 = retry_policy.backoff_delay(error_count)
        提高 error_to_rise 除非 retry_policy.should_retry_overload?(error_count, 延迟, 上下文: 上下文)

        log_retry(e, 消息: ' 写入重试(过载退避) ')
        睡眠(延迟)
        开始
          server = select_server(
            集群, ServerSelector.主节点, 会话, server,
            错误: e, timeout: 上下文.剩余超时秒数
          )
        救援 错误, 错误::AuthError => select_err
          error_to_rise.add_note(" Later retry failed: #{ select_err.}: #{ select_err}")
          提高 error_to_rise
        end
        重试
      else
        e.add_note('已禁用重试')
        提高 e
      end
    end
  else
    legacy_write_with_retry(server, 上下文: 上下文, )
  end
end

# retry_write_allowed? (session, write_concern) ⇒ true | false

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

查询会话和写关注是否支持重试写入。

参数:

返回:

  • ( true | false )

    是否允许写入重试。

由于:

  • 2.19.0



159
160
161
162
163
# File 'lib/ Mongo/retryable/write_worker.rb', line 159

def retry_write_allowed?(会话, write_concern)
  return false 除非 会话&。retry_writes?

  write_concern.nil? || writeConcern.获取(write_concern).已确认?
end

# write_with_retry (write_concern, context:, ending_transaction: false, &block) {|connection, txn_num, context| ... } ⇒ 结果

此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。

注意:

这只在非主节点故障时重试操作,因为这是我们可以确定尚未发生部分写入的唯一情况。

通过一次或多次让出传递的区块来实现写入重试功能。

如果提供了会话(因此,部署支持会话),并且在客户端上启用了新式重试写入,则会调用新式重试逻辑。 否则,将调用传统重试逻辑。

如果ending_transaction参数为true,表示正在提交或中止事务,则该操作只执行一次。 请注意,由于事务需要会话,因此如果ending_transaction 为 true 且会话为 nil,则此方法将引发 ArgumentError。

例子:

执行写入。

write_with_retry do
  ...
end

参数:

  • write_concern ( nil | Hash | WriteConcern::Base )

    写关注(write concern)。

  • ending_transaction ( true | false ) (默认为: false

    如果写入操作是 abortTransaction 或 commitTransaction,则为 true,否则为 false。

  • 上下文 ( Context )

    操作的上下文。

  • ( Proc )

    要执行的区块。

收益参数:

  • 连接 (连接)

    应通过其发送写入的连接。

  • txn_num ( Integer )

    事务编号(不是ACID类型)。

  • 上下文 ( Operation::Context )

    操作上下文。

返回:

  • (结果)

    操作的结果。

由于:

  • 2.1.0



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ Mongo/retryable/write_worker.rb', line 63

def write_with_retry(write_concern, 上下文:, ending_transaction: false, )
  会话 = 上下文.会话

  确保有效状态!(ending_transaction, 会话)

  除非 ending_transaction || retry_write_allowed?(会话, write_concern)
    return legacy_write_with_retry(nil, 上下文: 上下文, )
  end

  # 如果我们在这里,会话不为零。 为 nil 的会话会产生
  # retry_write_allowed 失败?检查。

  server = select_server(
    集群, ServerSelector.主节点,
    会话,
    timeout: 上下文.剩余超时秒数
  )

  除非 ending_transaction || server.retry_writes?
    return legacy_write_with_retry(server, 上下文: 上下文, )
  end

  modern_write_with_retry(会话, server, 上下文, )
end