WinSNMPのタイムアウト動作について
Visual Sdudio2012で作成したプログラムを2019(C++11→14にも変更)にマイグレを行ったアプリ開発を行っていますが、2012でも起きていたWinSNMPを利用したもので稀に発生する事象があります。
WinSNMPを利用して、数千スレッドから定期的にGetRequest(Next含む)または、ユーザーの要求によりSetRequestを並行して行っているのですが、設定したタイムアウト値とは異なる秒数で、SNMPAPI_CALLBACKがタイムアウトで呼ばれる場合が稀に発生します。
設定値を超えることは問題ないのですが、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によるイベント待ち)
-- ここまで --
上記、⑫で設定しているタイムアウト値を大幅に下回る秒数でコールバックが呼ばれることが稀にあります。
私のAPI使用方法が間違っている場合は、稀に起きるという事ではなく、もっと発生頻度がが上がるかと思います。また、意図的に応答を返さないアプリを作成して確認しましたが、通常時はタイムアウト値より少し多めでタイムアウト判定をしてくれるのは確認済みです。
色々Web上で検索してみましたが、バグ情報なども見られずにいます。
同じようなは経験をしている方が居ましたらご助言をいただけると思います。