タスクキューによるタスク実行
GAEは一つの処理を30秒以内に終わらせなければならないため、時間のかかる処理はタスクキューを使って分割実行する必要がある。
キューの登録はWEB-INF以下にqueue.xmlを作って登録する。
rateは追加されたキューの実行間隔。
1/sであれば、1秒に1回のペースで未実行のキューを実行する。
<queue-entries> <queue> <name>queueServlet</name> <rate>1/s</rate> </queue> </queue-entries>
キューの追加はQueueFactory.getQueue("queueServlet")で作成したqueueに対し、addする。
TaskOptions.Builder.withUrlで、URLを指定することができるが、指定しない場合は、/_ah/queue/queueServletというURLが使われる。
TaskOptions.Builder.withParamでパラメータを指定することができる。
Queue queue = QueueFactory.getQueue("queueServlet"); for (int i = 0; i < 10; i++) { queue.add(TaskOptions.Builder.withParam("count", Integer.toString(i))); }
指定したパラメータはHttpServletRequestのgetParameterで取り出せる。
public class QueueServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Logger logger = Logger.getLogger(QueueServlet.class.getName()); logger.info("count is " + req.getParameter("count")); } }
QueueServletはweb.xmlに/_ah/queue/queueServletで登録すればよい。
<servlet> <servlet-name>queueServlet</servlet-name> <servlet-class>com.kumoniji.server.QueueServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>queueServlet</servlet-name> <url-pattern>/_ah/queue/queueServlet</url-pattern> </servlet-mapping>
上の結果は以下のようになる。
1秒間隔で実行されているようには見えず、順番もばらばらな理由はよくわからない。
ともかく、順番に依存する処理は入れないほうが無難。
情報: count is 4 情報: count is 0 情報: count is 5 情報: count is 8 情報: count is 6 情報: count is 9 情報: count is 3 情報: count is 1 情報: count is 7 情報: count is 2
作成中のアニメ特化アンテナサイト
http://kumo2ji.appspot.com/
GWTでブラウザバックを実行する
GWTでブラウザバックを行うためには、HyperlinkとHistoryを使う。
まずは適当にUiBuilderでUIを作る。
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"> <ui:style> </ui:style> <g:HTMLPanel> <g:VerticalPanel> <g:HorizontalPanel> <g:SimplePanel ui:field="hyperlink1Panel"/> <g:SimplePanel ui:field="hyperlink2Panel"/> </g:HorizontalPanel> <g:Label text="New Label" ui:field="resultLabel"/> </g:VerticalPanel> </g:HTMLPanel> </ui:UiBinder>
Hyperlinkのインスタンス化で第1引数に表示文字、第2引数にトークン(URLの#以降に追加される文字列)を指定する。
ブラウザバックを有効化させるためにはHistory.addValueChangeHandlerにハンドラを登録すればよい。
このとき、引数のevent.getValue()でHyperlinkのインスタンス化で第2引数に指定した文字列を取得することができる。
public class MainComposite extends Composite { private static MainCompositeUiBinder uiBinder = GWT .create(MainCompositeUiBinder.class); @UiField SimplePanel hyperlink1Panel; @UiField SimplePanel hyperlink2Panel; @UiField Label resultLabel; interface MainCompositeUiBinder extends UiBinder<Widget, MainComposite> { } public MainComposite() { initWidget(uiBinder.createAndBindUi(this)); Hyperlink link1 = new Hyperlink("link1", "link1Token"); hyperlink1Panel.add(link1); Hyperlink link2 = new Hyperlink("link2", "link2Token"); hyperlink2Panel.add(link2); History.addValueChangeHandler(new ValueChangeHandler<String>() { @Override public void onValueChange(ValueChangeEvent<String> event) { resultLabel.setText(event.getValue()); } }); } }
作成中のアニメ特化アンテナサイト
http://kumo2ji.appspot.com/
条件を指定してDatastoreから情報を取得する
Datastoreにキー名"http://otanews.livedoor.biz/"、
"title"プロパティ"萌えオタニュース速報"のEntityを登録した状況のとき、
"title"を指定して、Entityを取得する。
Entity entity = new Entity("blog", "http://otanews.livedoor.biz/"); entity.setProperty("title", "萌えオタニュース速報"); DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); ds.put(entity);
Entityを取得するときに条件を指定するためにはQueryとFilterを用いる。
QueryはKind名を引数にインスタンス化する。
queryのsetFilterメソッドにプロパティの条件を指定する。
今回の場合は、"title"プロパティが"萌えオタニュース速報"のEntityを取得したいので、
FilterOperator.EQUALを用いる。
後は、queryをDatastoreServiceのprepareの引数にいれ、PreparedQueryにしてから、asQueryResultListメソッドで結果をQueryResultListとして得る。
PreparedQueryにはasListやasIteratorメソッドもあるが情報量はasQueryResultListが一番多い。(Cursor情報を持っている)
asQueryResultListの引数にFetchOptionsを指定する必要があるが、数の上限やCursorの指定がない場合は、FetchOptions.Builder.withDefaults()でよい。
Query query = new Query("blog"); query.setFilter(new FilterPredicate("title", FilterOperator.EQUAL, "萌えオタニュース速報")); DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); QueryResultList<Entity> entityList = ds.prepare(query).asQueryResultList(FetchOptions.Builder.withDefaults());
作成中のアニメ特化アンテナサイト
http://kumo2ji.appspot.com/
Keyを指定してDatastoreから保存情報の取り出す
http://kumo2ji.hatenablog.com/entry/2013/07/23/194931
Datastoreに保存した情報はKeyを指定して取り出すことができる。
KeyはKeyFactory.createKey(Kind名, キー名)で作る。
entityに登録したプロパティはgetPropertyで取得することができる。
getPropertyの戻り値はObjectなので、適宜キャストする。
キー名はentity.getKey().getName()で取得できる。
Key key = KeyFactory.createKey("blog", "http://otanews.livedoor.biz/"); DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); Entity entity = ds.get(key); String title = (String)entity.getProperty("title"); String url = entity.getKey().getName();
作成中のアニメ特化アンテナサイト
http://kumo2ji.appspot.com/
DatastoreへのEntityの保存方法
GAEではNoSQLのDatastoreにデータを保存する。
Datastoreにデータを保存するためには、Entityを作り、DatastoreServiceのputに入れてやる。
EntityはKind名とキー名を指定してnewする。
これで、Datastoreで識別可能な名前をつけたことになるので、
保存したいプロパティをsetPropertyで指定していく。
Entity entity = new Entity("blog", "http://otanews.livedoor.biz/"); entity.setProperty("title", "萌えオタニュース速報"); DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); ds.put(entity);
作成中のアニメ特化アンテナサイト
http://kumo2ji.appspot.com/