- PR -

Processの非同期化について

投稿者投稿内容
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-07-16 10:58
話しを聞いていると、ますます非同期である必要が感じられませんね。
<img src="/ImageBuilder?xxx=xxxx...."/>
というような感じで十分じゃないでしょうか。。。
画像がない(生成中)ならば、代替画像(処理中を示すアニメーションGIF)で十分でしょう。

スレッドをセッションに拘束するというのは正直オススメできません。
何故かと言うと、スケールアウトが容易にできなくなるためです。
未記入
大ベテラン
会議室デビュー日: 2008/07/11
投稿数: 182
投稿日時: 2008-07-17 11:47
ありがとうございます。

Threadの方でやってみました。問題なく表示・メモリも大丈夫(?)なようです。
おっしゃるように同期で行うのが、一番良いのですが、画面の表示に1分以上
かかってしまうのが、今回の修正の要件でした。

どうしても、5回回し、画像を生成するというのは、優先度が上位で仕様変更不可
となり、このように非同期で実現しようと言う事でした。

imgのストリームの出力で十分と考えてます。ただ、処理が重いのはこのexeの方で、
メモリを搭載したマシンでも多少のパフォーマンスUPを望めるというものでした。

ありがとうございました。
未記入
大ベテラン
会議室デビュー日: 2008/07/11
投稿数: 182
投稿日時: 2008-07-19 17:01
再びすいません。

かつのりさんのおっしゃるようにimgタグのsrcでサーブレット実現できているのですが、これにAjaxを絡めさせたい場合(非同期の1秒リロード)はどのように修正するのでしょうか?(サーブレットの戻り値ストリームと呼び出し側のインターフェースは変えないでいいと思っているのですが・・。)

Ajaxを使うと普通のActionであれば、JavaScriptで
**********************************************************************
// Ajax利用時共通通信メソッド
function newXMLHttpRequest() {
/* Create a new XMLHttpRequest object to talk to the Web server */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}
@end @*/
if (!xmlHttp && typeof XMLHttpRequest != "undefined") {
xmlHttp = new XMLHttpRequest();
}
return xmlHttp;
}

function callServer(xmlHttp, parmId) {
if ((parmId == null || parmId == "")) {
return;
}
// 呼出し先URL
var url = "http://localhost:8080/app/" + "XXXX.do?parm=" + parmId;
// 接続
xmlHttp.open("GET", url, false);
xmlHttp.send(null);
}

//例
function updatePage(parmId, rank) {
// Ajax接続形式からCreate(XMLHttpRequest)
var xmlHttp = newXMLHttpRequest();//new ActiveXObject("Msxml2.XMLHTTP.3.0");

// 呼出し先URL接続
callServer(xmlHttp, parmId);

// 通信結果取得成功
if (xmlHttp.readyState == 4) {
var ret = xmlHttp.responseText;
var arr = ret.split("|");
if (0 < arr.length) {
for(var i=0; i<arr.length; i++) {
var objHTML = eval("document.forms[0].select"+(rank*1+i+1));
if(objHTML) {
getOptions(objHTML, arr[i]);
}
}
} else {
for(var i=0; i<3; i++) {
var objHTML = eval("document.forms[0].select"+(rank*1+i+1));
if (objHTML) {
getOptions(objHTML, "");
}
}
}
}
}

@例(JSP-プルダウンが選択された時のサンプル)
<html:select property='select' onchange="updatePage(this.value, '1');">
<bean:define id="options" name="LIST" />
<html:options collection="options" property="id" labelProperty="name" />
</html:select>
**********************************************************************

<img src="http://localhost:8080/app/servlet...
と、している場合どのように1秒リロードをかけられるでしょうか?

よろしくお願いします。
わたなべ
大ベテラン
会議室デビュー日: 2007/12/09
投稿数: 123
お住まい・勤務地: 札幌
投稿日時: 2008-07-19 18:19
Ajaxで画像のパスを取得して、imgのsrcに書き込めばいいんじゃない?
取得した画像パスが特定の文字列を含んでいるならば、繰り返すとかすればいいだけ。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-07-19 20:16
既にファイル名が分かっているなら、Ajaxすらいらないですね。
setIntervalでimg.srcを設定すればいいだけです。

自分がやるとすれば、
コード:
<!--読み込み中を示すアニメーションGIF-->
<img id="img1" src="loading.gif"/>
<img id="img2" src="loading.gif"/>
<img id="img3" src="loading.gif"/>

<script type="text/javascript">
    window.onload = function(){
        document.getElementById("img1").src = "${img1のURLのEL式}";
        document.getElementById("img2").src = "${img2のURLのEL式}";
        document.getElementById("img3").src = "${img3のURLのEL式}";
    };
</script>


具体的に何パーセントとか出すわけでなければ、これで十分でしょう。
最初にimgタグでグルグル回るローディング画像を表示して、
onloadで表示の時間のかかる画像を読み込ませています。
読み込まれれば表示されますし、読み込まれるまではローディング画像のままです。
未記入
大ベテラン
会議室デビュー日: 2008/07/11
投稿数: 182
投稿日時: 2008-07-20 09:41
ありがとうございます。

現在のServletのストリームで返す方法を守りたいのは、前述のThreadに絡んで、この画面の表示にはこのThreadのindexでステータスを見る。処理中の場合はこの画像。ステータスが終了しているのに画像が無い場合はこの画像。

また、一番にこの機能自体画像出力のレンスポンスがあまりにも遅いのであれば、別PCに移行しようかと、議論されています。後々の修正の為にもこのインターフェースは守った方がいいと考えてます。

また、Ajaxを使いたいのは1秒リロードでsubmitすると、ブラウザが騒がしくなってしまう為、クライアントユーザには違和感を与えず、裏で常にThreadの状態をチェックしつつ表示をすると言う事を実現したいと思ってます。
(※画像サイズによる表示の時間の問題は確かにありますね・・。かつのりさんのサンプルを見るとやっぱり今度はブラウザの表示時間も加味しないといけないですね。1秒が短すぎるかもしれませんね。)

ありがとうございます。

画面全体のsubmitありのロジックは、javascriptでsetTimeout('javascript:メソッド',1000*1);で実現できました(或いはmetaタグ)が、このimgタグだけ対象に1秒リロードと指定URLを叩くということが可能でしょうか?(Javascriptでも構わないのですが・・。)

よろしくお願いします。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-07-20 14:57
わたなべさんや、私の書き込みでピンときませんでしたか。。。
setTimeoutでもsetIntervalでもいいので、
IMGタグオブジェクトのsrc属性を定期的に書き換えるだけです。
未記入
大ベテラン
会議室デビュー日: 2008/07/11
投稿数: 182
投稿日時: 2008-07-20 19:33
ありがとうございます。

仰るとおりできました。JavaScriptの質問になってしまいますが、


@@ html
<img id="img1" src="spacer.gif"/>

@@ Javascript
setTimeout("test()",1000 * 1);

test() {
var url = "http:localhost:8080/app/servlet/test.do?par=" + document.forms[0].label1.value;
document.getElementById("img1").src = url;
}

こんな感じで一度は出来たんですが、そのうちout of memory line:30と出るようになりました。ぐぐるとAdobeのFlashのIEのバグとの意見が多く見られましたが、FireFoxでは実現できなかったりと・・。

setIntervalも同様にでました。こちらに関してお分かりになる方よろしくお願いします。

スキルアップ/キャリアアップ(JOB@IT)