Tarantoolのアプリケーション。 パート3.テストと起動

Tarantoolのアプリケーションは、基本的にAPIとして使用されるストアドプロシージャのコレクションです。 データはストレージ側で処理されるため、パフォーマンスが大幅に向上します。 ただし、ストアドプロシージャのサポートは悪夢のようです。







たぶん。 しかし、今日ではありません。







今日は、アプリケーションの品質を確保する問題を検討します。 特に、テストについて説明し、生産を開始する方法、コネクタを使用する方法を確認し、データスキームの移行の複雑さについても説明します。













Tarantoolアプリケーションシリーズの内容



- パート1:ストアドプロシージャ

- パート2:OAuth2認証

- パート3:テストと起動







この連載のすべての例は、 tarantool-authmanユーザー認証アプリケーションに基づいていることを思い出させてください。







テスト中



テストは、品質を改善するための1つの方法にすぎません。







ストアドプロシージャの場合、機能テストは現在のAPIをサポートするための優れたオプションです。 テストには、Tarantoolに組み込まれたtap(Test Anything Protocol)モジュールが使用されます。 これには、Luaオブジェクトの基本的なチェックと比較のためのいくつかのメソッドが含まれています。 ユーザー登録auth.registration(email)



2つのケースをテストしてみましょう。







 local case = {} local tap = require('tap') local response = require('authman.response') local error = require('authman.error') local db = require('authman.db') local config = require('test.config') --     local auth = require('authman').api(config) local test = tap.test('registration_test') --  space     function case.before() db.truncate_spaces() end function case.after() end function test_registration_succes() local ok, code ok, code = auth.registration('test@test.ru') -- ,    ,     —  test:is(ok, true, 'test_registration_succes user created') test:isstring(code, 'test_registration_succes code returned') end function test_registration_user_already_exists() local ok, code, got, expected, user ok, code = auth.registration('test@test.ru') --    API,      ok, user = auth.complete_registration('test@test.ru', code, 'password') -- ,      --    ,         Lua- got = {auth.registration('test@test.ru'), } expected = {response.error(error.USER_ALREADY_EXISTS), } -- is_deeply       Lua- test:is_deeply(got, expected, 'test_registration_user_already_active') end case.tests = { test_registration_succes, test_registration_user_already_exists } return case
      
      





次に、テストを実行する小さなスクリプトを作成します。 before



メソッドとafter



メソッドを考慮することを忘れないでください。これにより、テストが簡単になります。







 --  ,   Tarantool box.cfg { listen = 3331, } local TEST_CASES = { 'test.case.registration', } function run() for case_index = 1, #TEST_CASES do local case = require(TEST_CASES[case_index]) for test_index = 1, #case.tests do --    case.before() case.tests[test_index]() case.after() end end end run()
      
      





テスト実行結果:







 $ tarantool test/authman.test.lua ... TAP version 13 ok — test_registration_succes user created ok — test_registration_succes code returned ok — test_registration_user_already_active
      
      





インスタンスの起動



アプリケーションは作成およびテストされています。つまり、実稼働環境にデプロイする時間です。







Tarantoolインスタンスは、 組み込みのtarantoolctlユーティリティを使用して管理されます 。 まず、アプリケーションでインスタンスを作成します。 ユーザーを追加して権限を与えることを忘れないでください。







 box.cfg { listen = 3331; } local function bootstrap() box.schema.user.create('my_user', {password = '123'}) box.schema.user.grant('my_user', 'read,write,execute', 'universe') end box.once('init_user', bootstrap) config = { --   } --   auth  auth = require('auth').api(config)
      
      





次に、instances.enabledディレクトリからこのファイルへのシンボリックリンクを作成します。







 sudo ln -s /etc/tarantool/instances.available/auth.lua /etc/tarantool/instances.enabled/auth.lua
      
      





tarantoolctlを実行し、Tarantoolに接続してアプリケーションメソッドを使用できることを確認します。







 $ tarantoolctl start auth $ tarantoolctl enter auth connected to unix/:/var/run/tarantool/auth.control unix/:/var/run/tarantool/auth.control> ok, user = auth.registration('ivanov@mail.ru') unix/:/var/run/tarantool/auth.control> ok, user = auth.complete_registration('ivanov@mail.ru', user.code, '123') unix/:/var/run/tarantool/auth.control> user --- - is_active: true email: ivanov@mail.ru id: 8cd27d26-3974-43d6-a2b2-87202664753d ...
      
      





問題が発生した場合は、ログ/var/log/tarantool/auth.lua



確認する必要があります。 Tarantoolサーバーの管理の詳細については、ドキュメントをご覧ください。







コネクター



ストアドプロシージャの利点の1つは、異なるプログラミング言語で記述されたサービスに共通のインターフェイスを提供することです。













Pythonコネクタを使用してTarantoolを非同期的に使用する例を考えてみましょう。







 import asyncio import asynctnt async def create_user(): tnt_connection = asynctnt.Connection( host='127.0.0.1', port='3367', username='my_user', password='123' ) #    user_data = await tnt_connection.call( 'auth.registrtion', ['exaple@mail.ru', ] ) await tnt_connection.disconnect() #    loop = asyncio.get_event_loop() loop.run_until_complete(create_user())
      
      





組み込みのnet.box



モジュールを使用して、別のTarantoolインスタンスからTarantoolと対話することもできます。 詳細については、ドキュメントを参照してください







データ移行



アプリケーションがすでに戦闘で実行されている場合の一般的なタスクは、データスキームを変更することです。 たとえば、ユーザーはgender



フィールドを追加する必要があります。













これを行うには、スペースauth_user



すべてのデータを変更するスクリプトを作成します。 スクリプト自体をアプリケーション初期化呼び出しに追加でき、 box.once



関数box.once



繰り返し呼び出しbox.once



制限します。







 local fiber = require('fiber') local function migrations() --      box.once('20171101_add_gender', function () local counter = 0 --  space        --       for _, tuple in box.space.auth_user:pairs( nil, {iterator=box.index.ALL} ) do local user_tuple = tuple:totable() --      user_tuple[4] = get_user_gender() box.space.auth_user:replace(user_tuple) counter = counter + 1 end end) end migrations()
      
      





移行には長い時間がかかる場合がありますが、実行のメインスレッドはブロックされません。 これは、 replace



メソッドが暗黙的にyield



呼び出すyield



です。 実行スレッドを明示的に解放するには、 fiber.sleep(0)



メソッドを呼び出す必要があります。 詳細については、ドキュメントを参照してください







次は?



タランツールは静止しておらず、積極的に開発中です。







このチュートリアルシリーズの記事以外にも、独自のサービスを作成する際に注意すべき重要な問題がいくつかあります。









すべてのコード例はtarantool-authmanアプリケーションからのものであることを思い出してください。 また、開発中であり、現在はOauth2-serverとして使用できます。







記事シリーズの範囲を超える質問がまだある場合は、 電報チャットで質問することができます。 レスポンシブなTarantoolコミュニティはあなたを助けることができるでしょう。







第三部を待っていたすべての人に感謝します。







じゃあね!







Tarantoolコミュニティは 6月21日にモスクワで最初のインメモリコンピューティング会議を開催します。 報告はまだ受け付けられており、論文の募集は開いています。



All Articles