サーバーの起動時に実行される遅延タスクを作成しました。ここでは、エンドポイントは、最終的にタスクを実行ContextListenerです:遅延タスク:しばらくしてnullになる参照。
public class ServerSetupListenerVer1 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//Endpoint service
final LearnerProfileVer2PersistenceEndpoint learnerEndpoint = new LearnerProfileVer2PersistenceEndpoint();
final TutorProfileVer2PersistenceEndpoint tutorEndpoint = new TutorProfileVer2PersistenceEndpoint();
//Retrieve the dummy profile data
final LearnerProfileVer1[] learnerProfiles = (LearnerProfileVer1[]) ProfileUtils.getJSONToProfiles(STATUS_LEARNER);
final TutorProfileVer1[] tutorProfiles = (TutorProfileVer1[]) ProfileUtils.getJSONToProfiles(STATUS_TUTOR);
//Insert this data into the datastore
ObjectifyService.run(new VoidWork() {
@Override
public void vrun() {
for(LearnerProfileVer1 profile : learnerProfiles){
learnerEndpoint.insert(profile);
}
for(TutorProfileVer1 profile : tutorProfiles){
tutorEndpoint.insert(profile);
}
}
});
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
あなたは、私がここへの参照を保管しております2つのエンドポイントがあることがわかります。これらの両方のエンドポイントには、実行するための共通の遅延タスクがあります。延期タスクを以下に示します。
基本的にstatic class LocationTask implements DeferredTask {
private Account acc;
private LatLng geoCoordinates;
private int retries = 0;
public LocationTask(final Account acc, final LatLng geoCoordinates) {
logger.info("Profile at the time of task creation: " + acc.getProfile());
this.acc = acc;
this.geoCoordinates = geoCoordinates;
}
@Override
public void run() {
logger.info("Profile at the time of DeferredTask.run() call " + acc.getProfile());
String response = LocationUtil.getFormattedAddress(geoCoordinates);
if((response = checkResponseCode(response)) != null){
// Stash the address into the Datastore
logger.info("Profile to be updated with location-info: " + acc.getProfile());
acc.setLocationInfo(new Account.LocationInfo(response));
ofy().save().entity(acc).now();
}
}
private String checkResponseCode(String response){
if(response == null){
return null;
}
if(response.equals("ZERO_RESULTS")){
return null;
}
else if(response.equals("OVER_QUERY_LIMIT")){
// We can re-request without any GET params except the LatLng
if(retries ++ == 1){
return null;
}
return checkResponseCode(LocationUtil.getFormattedAddress(geoCoordinates, null));
}
else if(response.equals("REQUEST_DENIED")){
return null;
}
else if(response.equals("INVALID_REQUEST")){
return null;
}
else if(response.equals("UNKNOWN_ERROR")){
return null;
}
else{
return response;
}
}
}
、これらのエンドポイントは客観化を使用してデータストアにアカウントを挿入しますが、単にアカウントを挿入する前に、私は延期タスクを使用して、{緯度、経度}のアドレスを計算することを望んでいました。問題は、Accountクラス内のプロファイルへの参照が、タスクの実行時に消えてしまうことです。私はログステートメントを通してこれを確認しました。遅延タスクのコンストラクタのlogステートメントは、プロファイルの内容を出力しますが、run()
メソッドからログオンしたときには同じプロファイルがnullになります。
驚くべきことは、LatLng geoCoordinates
のparamが生きてプロファイル自体の内部から検索されたことです。私が直接参照していない(paramsを介して)フィールドだけが生きていません。私はこれがタスクのシリアル化と関係しているのかどうか疑問に思っていました...
タスクは、エンドポイント要求(一度に1500)が処理された後に実行を開始することにも注意してください。次のように
また、新しいタスクは、各アカウントの作成のために作成されます。
void scheduleLocationInfoUpdation(final Account acc, final LatLng geoCoordinates){
if(geoCoordinates == null){
return;
}
//Using a deferred task
Queue queue = QueueFactory.getDefaultQueue();
queue.addAsync(TaskOptions.Builder.withPayload(new LocationTask(acc, geoCoordinates)));
}
これは本当に奇妙なシナリオです。誰が何が間違っているのか分かりますか?