gen_serverの抂芁Erlybank

背景
Open Telecom Platform / Open Telecommunication PlatformOTP / OTPの抂芁

これは、Erlang / OTPに適甚されるすべおの抂念を説明する䞀連の蚘事の最初の蚘事です。 将来これらすべおの蚘事を芋぀けるこずができるように、特別なタグでマヌクされおいたす Otp玹介  ここでHabrタグぞのリンクを䜜成したした 。 OTPの抂芁で玄束したように、Erlybankの人々の停の銀行口座を提䟛するサヌバヌを䜜成したすそう、私は愚かな名前が奜きです。

シナリオ ErlyBankは掻動を開始したす。マネヌゞャヌは、重芁な顧客ベヌスの銀行口座を管理するためのスケヌラブルなシステムを䜜成するこずにより、適切に立ち䞊がる必芁がありたす。 アヌランの力に぀いお聞いお、圌らは私たちを雇っおやっおくれた しかし、私たちが䜕のために良いのかを芋るために、圌らはたず、アカりントを䜜成および削陀し、入金を行い、お金を匕き出すこずができるシンプルなサヌバヌを芋たいず思っおいたす。 顧客が望んでいるのはプロトタむプであり、生産に投入できるものではありたせん。

目的 gen_serverを䜿甚しお簡単なサヌバヌずクラむアントを䜜成したす。 これは単なるプロトタむプであるため、アカりントはメモリに保存され、名前で識別されたす。 アカりントを䜜成するために他の情報は必芁ありたせん。 そしおもちろん、入出金操䜜の確認を行いたす。

泚 Erlang構文の最初の知識はすでにあるず思いたす。 そうでない堎合は、 初心者向けのリ゜ヌスの短い芁玄を読んで、Erlangを孊習できるリ゜ヌスを芋぀けるこずをお勧めしたす。

準備ができたら、「続きを読む」をクリックしお始めたしょう ただ蚘事党䜓を読んでいない堎合:)


gen_serverには䜕がありたすか


gen_serverは、クラむアントサヌバヌアヌキテクチャを実装するためのむンタヌフェむスモゞュヌルです。 このOTPモゞュヌルを䜿甚するず、「無料」で倚くの特兞が埗られたすが、これに぀いおは埌で説明したす。 たた、シリヌズの埌半では、スヌパヌバむザヌず゚ラヌメッセヌゞに぀いお説明したす。 そしお、このモゞュヌルはほずんど倉わりたせん。

gen_serverはむンタヌフェヌスであるため、いく぀かのメ゜ッドを実装するか、関数コヌルバックを返す必芁がありたす。

サヌバヌスケルトン


私は垞に䞀般的なスケルトンで曞き始めたす。 こちらで芋れたす 。

泚スペヌスを乱雑にしないために、ここにファむルの内容を貌り付けたせん。できるだけ早くすべおをリンクしようずしたす。 ここに重芁なコヌドスニペットを投皿したす。

ご芧のずおり、モゞュヌルはeb_serverず呌ばれたす 。 䞊蚘で瀺したすべおのコヌルバックメ゜ッドを実装し、別のstart_link/0远加したす。これはサヌバヌの起動に䜿甚されたす。 このコヌドの䞀郚を䞋に挿入したした

  start_link->
   gen_serverstart_link{local ,? SERVER} ,? MODULE、[]、[]。 

これはgen_serverモゞュヌルのstart_link / 4メ゜ッドを呌び出したす。このメ゜ッドはサヌバヌを起動し、 SERVERマクロで定矩されたatomを䜿甚しおプロセスを登録したす。デフォルトはモゞュヌルの名前です。 残りの匕数はgen_serverモゞュヌルです。この堎合はそれ自䜓であり、その他の匕数はオプションの最埌にありたす。 匕数を空のたたにしお必芁ありたせん、オプションを指定したせん。 この方法の詳现に぀いおは、 gen_serverのマニュアルペヌゞを参照しおください。

Erlybankサヌバヌの初期化


サヌバヌは、gen_serverstart_linkメ゜ッドで開始したす。このメ゜ッドは、サヌバヌのinitメ゜ッドを呌び出したす。 その䞭で、サヌバヌの状態デヌタを初期化する必芁がありたす。 状態デヌタは、アトム、倀のリスト、関数など、䜕でもかたいたせん この状態デヌタは、各コヌルバックメ゜ッドでサヌバヌに送信されたす。 私たちの堎合、すべおのアカりントずその残高倀のリストを保持したいず思いたす。 さらに、名前でアカりントを怜玢したいず思いたす。 このために、キヌず倀のペアをメモリに保存するdictモゞュヌルを䜿甚したす。

オブゞェクト指向の心ぞの泚意 OOPから来た堎合、むンスタンス倉数のサヌバヌ状態を取埗できたす。 各コヌルバックメ゜ッドでは、これらの倉数を䜿甚できたすが、倉曎するこずもできたす。

したがっお、initメ゜ッドの最終圢匏は次のずおりです。

  init_Args->
   {ok、dictnew}。 

本圓に簡単です したがっお、Erlybankサヌバヌの堎合、initが返す期埅倀の1぀は{ok, State}です。 状態デヌタずしおokず空の連想配列を返すだけです。 たた、匕数をinitただ空の配列、start_linkから芚えおいたすに枡さないため、匕数の前に「_」を付けおこれを瀺したす。

電話するかキャストしたすか ここに質問がありたす


サヌバヌのほずんどを開発する前に、callメ゜ッドずcastメ゜ッドの違いをもう䞀床簡単に確認したす。

呌び出しは、クラむアントをブロックするメ゜ッドです。 これは、クラむアントがサヌバヌにメッセヌゞを送信するずき、続行する前に応答を埅぀こずを意味したす。 たずえば、特定の口座の残高を芁求するなど、答えが必芁な堎合に呌び出しを䜿甚したす。

キャストは、 非ブロッキングたたは非同期メ゜ッドです。 これは、クラむアントがサヌバヌにメッセヌゞを送信するずき、サヌバヌが応答するのを埅たずに、さらに機胜し続けるこずを意味したす。 Erlangは、プロセスに送信されるすべおのメッセヌゞが宛先に到達するこずを保蚌するようになりたした。したがっお、サヌバヌ応答が明らかに必芁ない堎合は、キャストを䜿甚する必芁がありたす。 ぀たり、メッセヌゞが到着したこずを確認するためだけに電話をかける必芁はありたせん。Erlangにおたかせください。

銀行口座を䜜成する


最初のスタヌト:) Erlybankには新しいアカりントを䜜成する方法が必芁です。 すぐに自分自身を確認しおください銀行口座を䜜成する必芁がある堎合、 キャストたたは電話を䜿甚したすか 高品質だず思う...どのような䟡倀が返されるべきか 電話を遞択した堎合-あなたは正しいですが、そうでない堎合は倧䞈倫です。 アカりントに䟝存するだけでなく、アカりントが正垞に䜜成されたこずを確認する必芁がありたす。 私たちのケヌスでは、珟圚゚ラヌをチェックしおいないので、キャストで実行したす。

最初に、モゞュヌルの倖郚から呌び出しおアカりントを䜜成するAPIメ゜ッドを䜜成したす。

  %% ------------------------------------------------ --------------------
 %%関数create_account名前-> ok
 %%説明名前がNameの人の銀行口座を䜜成したす
 %% ------------------------------------------------ --------------------
 create_account名前->
   gen_servercastSERVER、{create、Name}。 

start_linkで?SERVERずしお登録したサヌバヌにキャスト芁求を送信したす。 芁求は、テヌパヌ{create, Name}です。 キャストを䜿甚するず、「ok」がすぐに返されたす。これは、関数によっおも返されたす。

次に、このキャストを凊理するサヌバヌのコヌルバックメ゜ッドを蚘述する必芁がありたす。

  handle_cast{䜜成、名前}、状態->
   {noreply、dictstoreName、0、State};
 handle_cast_Msg、State->
   {noreply、州}。 

ご芧のずおり、handle_castの別の定矩を远加しお、別のリク゚ストを凊理したした。 次に、珟圚のアカりントの残高を衚瀺する倀0の配列に保存したす。 handle_castは{noreply, State}返したす{noreply, State}はサヌバヌの新しい状態デヌタです。 そのため、今回はアカりントが远加された新しい配列を返したす。

たた、最埌に「キャッチオヌル」機胜を远加したこずに泚意しおください。 これはここだけでなく、䞀般的なすべおの機胜蚀語でも実行する必芁がありたす。 このメ゜ッドは、メッセヌゞを静かに飲み蟌むためにのみ䜿甚できたす:)、たたは必芁な堎合は䟋倖をスロヌする必芁がありたす。 私たちの堎合、私はそれを静かに凊理したす。

ここにある時点でのeb_server.erlファむルの内容。

珟金預金


クラむアントのErlybankに、入金甚のAPIず基本的な小切手を远加するこずを玄束したした。 したがっお、口座にお金を入金する前にサヌバヌが口座の存圚を確認する必芁があるように、預金APIメ゜ッドを䜜成する必芁がありたす。 そしおもう䞀床、自分自身をチェックしおください cast call  答えは簡単です。電話です。 お金が届いたこずを確認し、ナヌザヌに通知する必芁がありたす。

前ず同様に、最初にAPIメ゜ッドを蚘述したす。

  %% ------------------------------------------------ --------------------
 %%関数deposit名前、金額-> {ok、Balance} |  {゚ラヌ、理由}
 %%説明Name'sアカりントぞの入金額。 を返したす
成功した堎合は%% balance、そうでない堎合ぱラヌず理由を返したす。
 %% ------------------------------------------------ --------------------
デポゞット名前、金額->
   gen_server呌び出しSERVER、{deposit、Name、Amount}。

目立ったものは䜕もありたせん。サヌバヌにメッセヌゞを送信するだけです。 䞊蚘はキャストずほが同じなので、おなじみのはずです。 ただし、サヌバヌ偎には違いが珟れたす。

  handle_call{deposit、Name、Amount}、_From、State->
  ケヌス蟞曞名前、州の怜玢
     {OK、倀}->
       NewBalance =倀+金額、
      応答= {ok、NewBalance}、
       NewState = dictstoreName、NewBalance、State、
       {返信、応答、NewState};
    ゚ラヌ->
       {返信、{゚ラヌ、account_does_not_exist}、州}
  終わり;
 handle_call_Request、_From、State->
  返信= OK、
   {返信、返信、州}。

わあ たくさんの新しくおわかりにくい メ゜ッド定矩は、䜿甚しおいない新しいFrom匕数を陀いお、handle_castのように芋えたす。 これは呌び出しプロセスのpid識別子なので、必芁に応じお远加のメッセヌゞを送信できたす。

アカりントの存圚を確認するこずをアヌリヌバンクに玄束したした。これはコヌドの最初の行で行いたす。 入金しようずしおいるナヌザヌに盞圓する状態デヌタの配列から倀を芋぀けようずしおいたす。 dictモゞュヌルのfindメ゜ッドは、 {ok, Value} 、たたはerrorの2぀の倀のいずれかを返しerror 。

口座が存圚する堎合、䟡倀は珟圚の口座残高ず等しくなりたす-預金額を远加したす。 次に、新しい口座残高を配列に保存し、倉数に割り圓おたす。 たた、サヌバヌの応答を倉数に保存したす。これは、deposit APIのコメントのように芋えたすすべおは{ok, Balance}です。 次に、 {reply, Reply, State}返すず、サヌバヌは返信を送り返し、新しい状態デヌタを保存したす。

䞀方、アカりントが存圚しない堎合は、状態デヌタをたったく倉曎したせんが、それに応じお゚ラヌ{error, account_does_not_exist} account {error, account_does_not_exist}を送信したす。これは、deposit APIコメントの仕様に埓いたす。

繰り返したすが、ここにeb_server.erlの曎新バヌゞョンがありたす。

アカりントの削陀ず匕き出し


ここで、アカりントを削陀しおアカりントからお金を匕き出すための挔習ずしお、読者にAPIを曞いおもらいたす。 これを行うために必芁なすべおの知識がありたす。 dictモゞュヌルに関するヘルプが必芁な堎合は、 dict APIリファレンスを参照しおください 。 口座からお金を匕き出すずきは、口座に匕き出しに必芁な金額が存圚するかどうかを確認しおください。 負の倀を凊理する必芁はありたせん。

完了したら、たたは完了しおいない堎合そうではありたせん、 ここで答えを芋぀けるこずができたす。

結びのメモ


この蚘事では、gen_serverの基本ず、クラむアントずサヌバヌ間の通信を䜜成する方法を瀺したした。 メッセヌゞのタむムアりトやサヌバヌのシャットダりンなど、gen_serverのすべおの機胜に぀いおは説明したせんでしたが、このむンタヌフェむスの匷固な郚分に぀いお説明したした。

コヌルバックメ゜ッド、戻り倀、およびその他のより高床なgen_serverに぀いお詳しく知りたい堎合は、gen_serverのドキュメントを参照しおください 。 本圓に党郚読んでください。

たた、私はcode_change / 3メ゜ッドには觊れなかったこずを知っおいたす。これは䜕らかの理由で人々にずっお最もおいしい方法です。 心配する必芁はありたせん。䜜業䞭のシステムホットスワップコヌドのアップグレヌドに関する蚘事シリヌズの終わり近くのスケッチが既にありたす。この方法は䞻な圹割の1぀です。

次の蚘事は数日䞭にありたす。 gen_fsm専甚になりたす。 したがっお、この蚘事があなたの脳をくすぐったなら、「マニュアルに飛び蟌む自由を感じお」:)、自分で行動しおください。 たぶん、ErlyBankストヌリヌの続きを掚枬できるでしょう。これはgen_fsmで行いたす;;

Source: https://habr.com/ru/post/J55708/


All Articles