6

JTOpen のKeyedDataQueueクラスが提供する read() メソッドを使用すると、奇妙な動作が検出されました。

90 秒のタイムアウトを設定し、タイムアウトに達したときの読み取り実行の 99% で、呼び出し元のメソッドの実行が再開されます。

残りの 1% については、タイムアウトは考慮/到達されず、私の呼び出しメソッドはハングしたままです...

少し検索したところ、次の投稿を見つけました。

http://archive.midrange.com/java400-l/201112/msg00056.html

基本的に、私が疑ったことを確認します:

「また、DataQueue.read() タイムアウト機能はサーバー側であるため、TCP/IP 接続が静かに切断された場合 (これが根本的な原因であると私は信じています)、依然としてハングします。」

私は JTOpen のバージョン 7.2 を使用していますが、バージョン 7.9 が既に公開されていることに気付きました。私は 7.9 に更新しませんでした。これは、7.2 を使用している安定した重要なアプリケーションが多数あるためです。これは、7.9 への更新を検討する最初の実際のシナリオです。

その決定を支援するために、特にこの状況に遭遇し、最終的に JTOpen をアップグレードして解決した方からのフィードバックを本当にお待ちしています。

具体的には、この問題の回避策はありますか? JTOpen のアップグレードはこれに役立ちますか? JTOpen を 7.9 にアップグレードすると、7.2 で動作していた機能が壊れますか?

4

1 に答える 1

1

上記のように、データキューの読み取りタイムアウトはサーバー側です。iSeries とクライアントの間の TCP 接続が停止または停止した場合、クライアントはソケットがタイムアウトするまで待機します。私の解決策は、失速した読み取りを停止するためにフェイルセーフインタラプタを設定することです。これを行う方法の簡単なコード サンプルを次に示します。

    public class DataQueueListenerExample {
    //This executes our Interrupter after the specified delay.
    public final ScheduledThreadPoolExecutor interruptExecuter = new ScheduledThreadPoolExecutor(1);
    //the dataqueue object.
    protected DataQueue dataqueue;

    public DataQueueEntry read(int wait)
    {
        ScheduledFuture<?> future = null;
        try {
            //create our fail safe interrupter. We only want it to 
            //interrupt when we are sure the read has stalled. My wait time is 15 seconds
            future = createInterrupter(wait * 2, TimeUnit.SECONDS);
            //read the dataqueue
            return this.dataqueue.read(wait);
        } catch (AS400SecurityException e) {
        } catch (ErrorCompletingRequestException e) {
        } catch (IOException e) {
        } catch (IllegalObjectTypeException e) {
        } catch (InterruptedException e) {
            //The read was interrupted by our Interrupter
            return null;
        } catch (ObjectDoesNotExistException e) {
        } finally{
            //Cancel our interrupter
            if(future != null && !future.isDone())
                future.cancel(true);
            Thread.interrupted();//clear the interrupted flag

            interruptExecuter.shutdown();
        }
        return null;
    }


    public ScheduledFuture<?> createInterrupter(long timeout,TimeUnit timeunit)
    {
        return interruptExecuter.schedule(new Interrupter(),timeout,timeunit);
    }

    class Interrupter implements Runnable
    {
        final Thread parent;
        Interrupter()
        {
            this.parent = Thread.currentThread();
        }

        @Override
        public void run() {
            parent.interrupt();
        }
    }
    }

InterruptedException の後、新しい AS400 接続で DataQueue オブジェクトを再作成することを強くお勧めします。AS400 接続が停止している可能性があります。Thread.interrupt は非常に便利ですが、注意して使用してください。

于 2014-01-08T15:59:11.570 に答える