Eugenio Pace – Software as a Service Architecture Guidance
Published Tuesday, April 01, 2008 2:43 PM by eugeniop
LitwareHR on SSDS – Part IV – Data access enhancements 2: developing offline
SQL Server Data Service is well…an online service. That means that you have to be connected to the network 100% of the time if you are using it. What if you are not connected? well…you know the whole story.
つまり、、、SQL Server Data Service はオンライン・サービスである。 そのため、SSDS を使用している際には、100%の割合で、ネットワークに接続していなければならないことになる。 接続されていないと、いったいどうなるのだろう? そのストーリーを、これから知ることになる。
Our goal while developing LitwareHR was to actually make the dev team as independent and autonomous as possible. Notice I say the dev team, not the application itself. We were comfortable in taking a dependency with SSDS for runtime, that is when LitwareHR would be deployed in a production data center. But we wanted developers to be able to work even if they are flying on a plane with no connectivity (like I was!). In one sentence we wanted a "mock SSDS".
LitwareHR を開発する際に持っていた目的は、実質的に開発チームを、可能な限り独立させ、また、自立させることにあった。アプリケーション自体ではなく、開発チームについて言及していることに注意して欲しい。 ランタイムにおいて、SSDS に対する依存性を持つことに満足していた。 つまり、プロダクション・データセンターに、LitwareHR がディプロイされるときを想定していた。 しかし、空を飛んでいる飛行機のように、デベロッパーが接続性を持たないときであっても(私がそうであったように!)、開発環境が適切に機能することを望んだ。 一言でいうと、「mock SSDS」が欲しかった。
With this in mind, we developed a new proxy implementing the same interface the real proxy implements, but against a local SQL Server Express database.
それを念頭において、本当のプロキシーと同じインターフェイスを実装している、新しいプロキシーを開発した。しかし、そこでは、ローカルの SQL Server Express が用いられる。
Again: our goal was not to create full-fledged offline SSDS, but rather an implementation complete enough to support our TDD development practices, and "complete enough" is key here. We gradually made it more complex as needed by LitwareHR, so no guarantees that it would actually work in another application, and no optimizations whatsoever.
もう一度いうが、私たちのゴールは、完全なオフラインSSDS を作ることではなかった。しかし、私たちの TDD 開発プラクティスを支援するには、必要にして充分なものであった。そして「必要にして充分」な実装が、ここのでキーとなる。それは、 LitwareHR で必要とされるにつれて、段階的に複雑なものになっていった。したがって、別のアプリケーションで動くという保証はなく、また、最適化も考えていない。
Each dev in our team would configure he’s own solution to use the offline version of the proxy, make sure all tests pass, etc. then we would test against the real one. Features on the offline client were strictly added as necessary as we made progress with the project and tests passed with the real proxy but failed with the mocked one.
このチームの開発者たちは、オフラインのプロキシー・バージョンを使って、彼らのソリューションを構成していった。そして、すべてのテスト・パスを確認していった。 それから、本当の環境でテストが行われた。オフライン・クライアントにおける機能は、プロジェクトでの必要性に応じて追加された。そこでは、本当のプロキシーを用いたテストでは成功しても、モックでは失敗するほどの、厳密性が適用された。
The ProxyFactory class allows us to switch between one implementation and the other. Repository doesn’t really know or care about what version is using.
ProxyFactory クラスは、2つの実装の間での、切り替えを実現した。リポジトリは、どのバージョンが使われているのかを知らず、また、気にかけなくても良い。
The implementation is quite straight forward actually. There are 2 tables: CONTAINERS and DATA. The table CONTAINERS is only used to record the existence of a new container (because Containers can be empty). The table DATA contains the entity instances themselves. Structure of these tables is as simple as you could imagine:
この実装は、現実的に極めて単純なものである。 CONTAINERS と DATA という、2つのテーブルがある。 CONTAINERS テーブルは、新しい CONTAINERS の存在を記録するためだけに用いられる(CONTAINERS が空であり得るため)。 DATA テーブルは、エンティティーインスタンス自身を取り込む。 ご想像のとおり、これらのテーブル構造は単純である:
CONTAINER:
[containerId] [nvarchar](255) NOT NULL
DATA:
[containerId] [nchar](255) NOT NULL,
[id] [nvarchar](255) NOT NULL,
[version] [int] NOT NULL,
[kind] [nvarchar](255) NOT NULL,
[entity] [xml] NOT NULL
containerId, Id, version and kind translate into SSDS entities’ intrinsic properties. Queries against these being frequent. entity is the field that contains the serialized flexible entity.
containerId と、Id、version、kind は、SSDS エンティティーの本質的なプロパティに変換される。 それらに対するクエリーは、頻繁に発行される。entity は、シリアライズされた柔軟なエンティティを含むフィールドである。
The schema of the serialized entity is also quite simple and direct. A "book" entity with 3 fields: Title, ISBN and Author would be serialized like this:
シリアライズされたエンティティのスキーマも、きわめてシンプルでダイレクトなものである。「book」エンティティは、Title、ISBN、Author という、 3つのフィールドを持つ。 それらは、以下のようにシリアライズされるだろう:
<entity>
<field name="Title" type="System.String">The Aleph</field>
<field name="ISBN" type="System.String">78755</field>
<field name="Author" type="System.String">J.L.Borges</field>
</entity>
Operations like Insert, GetById, Delete and Update are trivial. Query is trickier because we had to (re) implement a parser for SLINQ. Good for us that SLINQ is fairly simple today. Once again, we just developed the basics so LitwareHR would work.
Insert、GetById、Delete、Update といった操作は、取るに足らないものである。クエリーに関しては、SLINQ 用のパーサーを実装する必要があるため、慎重を要する。 現時点の SLINQ が、かなりシンプルになったことは好都合である。もう一度いうが、LitwareHR を機能させるための、基本を開発したに過ぎない。
In a nutshell, it’s simply a translator from SLINQ syntax into a mix of T-SQL and XQuery. Searches involving intrinsic properties (Id, Kind, etc) are straight forward T-SQL statements. XQuery is only involved when the search criteria includes properties within the entity. For example:
簡単に言うと、それは、T-SQL と XQuery の複合体の中に、SLINQ シンタックスを変換するものとなる。 本質的なプロパティ(Id や kind など)を取り込む検索は、単純な T-SQL ステートメントに展開される。 XQuery が関連するのは、捜索の基準にエンティティ内のプロパティが含まれるときだけになる。 たとえば:
This query against a "C_1" container, looking for an entity with Id = E_1:
「C_1」コンテナに対するクエリーは、Id = E_1を用いるエンティティを検索する:
from e in entites where e.Id==’E_1" select e
is translated into:
上記は、以下に展開される:
SELECT id, entity, version, kind FROM DATA WHERE containerId=’C_1′ AND Id = ‘E_1′
and getting all entities with a flexible property named "Title" equal to "The Aleph":
すべてのエンティティが取得されるが、そこには「Title」という柔軟なプロパティ名が含まれ、「The Aleph」と一致する:
from e in entities where e["Title"]=="The Aleph" select e
will become:
上記は、以下に展開される:
SELECT id, entity, version, kind FROM DATA WHERE containerId=’C_1′ AND entity.value(‘(/entity/field[@name="Title"])[1]‘,’NVARCHAR(MAX)’) = ‘The Aleph’
We definitely recovered the investments we made in creating this facility. When we started development, SSDS was still changing and under development (this was far before MIX08), it was only available from our intranet (making it more difficult for our non-MSFT team members to access it: VPN, etc). With this approach, we definitely increased our productivity.
For serious, production offline access I’d look at Sync Services.
このファシリティを作成する投資からの、明確な回収に成功した。この試みが始まったとき(MIX08 以前)、まだ SSDS は変化している最中であり、開発中であった。それは、イントラネットからのみ利用が可能であり、チーム内の非 MSFT メンバーによる、VPN アクセスなどを困難にした。したがって、このアプローチにより、私たちの生産性は確実に向上した。厳密に言うと、プロダクション環境におけるオフライン・アクセスでは、Sync Services に注目している。








