About WinSNMP timeout behavior
日本語で失礼します。
Visual Sdudio2012で作成したプログラムを2019(C++11→14にも変更)にマイグレを行ったアプリ開発を行っていますが、2012でも起きていたWinSNMPを利用したもので稀に発生する事象があります。
WinSNMPを利用して、数千スレッドから周期的にGetRequest(Next含む)または、ユーザの要求によりSetRequestを並行して行っているのですが、設定したタイムアウト値とは異なる秒数で、SNMPAPI_CALLBACKが呼ばれる場合が稀に発生します。(WPARAMがSNMPAPI_TL_TIMEOUTで呼ばれる)
設定値を超えることは問題ないのですが、2秒程度を設定しているにもかかわらず、0ミリ秒~1秒未満という高速でSNMPAPI_CALLBACKが呼ばれるのですが、実際には要求は届いている状況で、タイムアウト値を誤って設定しているパターンが無いかは、ログを仕込んで確認済みとなります。
なお、マルチスレッドで同一機器への同時要求を行うと、要求先機器の性能が悪くなることを考慮し、同一機器への要求は、MUTEXでの排他を行っているので、1つの機器に対して複数スレッドで同時に要求は発生しない様に設計されています。
コードを載せることが出来ないので、以下はGetRequestで使用しているAPIと使用順序です。
①SnmpCreateSession:ここで作成したHSNMP_SESSIONを使用して以下を実施
②SnmpStrToEntity:自身のIPアドレス(127.0.0.1固定)で、HSNMP_ENTITYを生成
③SnmpStrToContext:要求先機器のコミュニティ名で、HSNMP_CONTEXTを生成
④SnmpStrToEntity:要求先機器のIPアドレスで、HSNMP_ENTITYを生成
⑤SnmpSetPort:上記④で取得したハンドルに対して、通信先ポートを指定
⑥SnmpSetTimeout:上記④で取得したハンドルに対して、タイムアウト値を指定
★ここへの値が正しい値になっていることは確認済み
⑦SnmpSetRetry:上記④で取得したハンドルに対して、リトライ回数(0固定)を指定
※アプリケーション内で制御したいため、送信リトライは意図的に無しにしている。
-- ここまでが、周期到達またはユーザ要求毎に1回実施 --
⑧SnmpCreateVbl:上記①で取得したハンドルを指定して、HSNMP_VBLを生成
⑨SnmpSetVb:上記①、⑧で取得したハンドルを指定して、取得したいOID分の情報を設定
⑩SnmpCreatePdu:上記①、⑧で取得したハンドルを指定して、HSNMP_PDUを生成
※request_idは同一周期内で、1~連番で、リトライ要求時にインクリメントしますが、仕様の都合で、同一周期内でも①~⑦を複数回行う場合があり、その場合は、同一周期であってもIDは再度1からふり直されますが、①~やり直すので、各種ハンドルは別物となります。
⑪SnmpSendMsg:上記①、②、③、④で取得したハンドルを指定して実行
⑫SNMPAPI_CALLBACKが呼ばれるのを待つ(CreateEventによるイベント待ち)
-- ここまで --
上記、⑫で設定しているタイムアウト値を大幅に下回る秒数でコールバックが呼ばれることが稀にあります。(WPARAMがSNMPAPI_TL_TIMEOUTで呼ばれる)
私のAPI使用方法が誤っている場合は、稀に起きるという事ではなく、もっと頻度が上がっていてもおかしくはありませんし、意図して応答を返さないアプリを作成して確認しましたが、通常時はタイムアウト値より少し多めでタイムアウト判定をしてくれるのは確認済みです。
色々Web上検索してみましたが、バグ情報なども見当たらず困っております。
同じようは経験をされている方が居ましたらご助言いただけると助かります。