ইভেন্টগুলি রিপ্লাই করার সময় কীভাবে সিআরকিউএসে পার্শ্ব প্রতিক্রিয়াগুলি পরিচালনা করবেন?


10

বলা হয়ে থাকে যে সিকিউআরএসে কোনও বাগ ঠিক করা সহজ, আপনি কেবল পুনরায় চালনা করুন এবং তারপরে ইভেন্টগুলি পুনরায় খেলুন।

তবে, যদি ইভেন্টগুলির মধ্যে কোনওটি আপনার নিয়ন্ত্রণে থাকা কোনও বাহ্যিক সিস্টেমকে গ্রাহকের কাছে "কোনও জিনিস প্রেরণ" না করার কারণ হয়ে থাকে তবে যদি আপনি কেবল ইভেন্টগুলি পুনরায় খেলুন তবে আইটেমটি দু'বার পাঠানো হবে।

কীভাবে সমাধান করবেন?

উত্তর:


6

আপনার পড়ার মডেলটির পরিস্থিতি সংশোধন করার ইভেন্টগুলির মধ্যে এবং ইভেন্টগুলি (সম্ভাব্য) বাহ্যিক সিস্টেমের অবস্থার পরিবর্তনকারীগুলির মধ্যে আপনাকে একটি স্পষ্ট বিভাজন তৈরি করতে হবে। উভয় রাজ্যকে এক সাথে সংশোধন করে কোনও "মিশ্র ইভেন্ট" না রয়েছে তা নিশ্চিত করুন। এইভাবে, আপনি আপনার ইভেন্টগুলিকে একটি নির্দিষ্ট "রিপ্লে মোড" এ রিপ্লে করতে পারেন যেখানে বাহ্যিক সিস্টেমের জন্য সেই ইভেন্টগুলি আবার চালিত হয় না। এই মোডে, আপনি বাহ্যিক সিস্টেম দ্বারা মূলত শুরু করা যে কোনও ইভেন্টকে "অনুকরণ" করে (এখন আপনি এগুলির পরিবর্তে পুনরায় খেলুন সারি থেকে এনেছেন)।

ভুলে যাবেন না, পুনর্নির্বাচিত পদক্ষেপটির অর্থ হ'ল পঠন মডেলটির স্থিতিকে সময়ের পূর্ববর্তী বিন্যাসে পুনরায় সেট করা। এটি সম্ভবত বাহ্যিক সিস্টেমগুলির অবস্থার জন্য আপনি (বা করার প্রয়োজন) কিছুই করতে পারেন না।


"ভুলে যাবেন না, পুনর্নির্বাচিত পদক্ষেপটির অর্থ হ'ল পাঠের মডেলটির স্থিতিকে সময়ের পূর্ববর্তী বিন্যাসে পুনরায় সেট করা। বাহ্যিক সিস্টেমগুলির অবস্থার জন্য এটি সম্ভবত আপনি কিছু করতে (বা করার প্রয়োজন) কিছু নয়" " -> তবে আমি কী চাই যদি আমার রিপ্লেটি শিপিংয়ের মতো ব্যর্থ বাহ্যিক সিস্টেমের কলগুলিতে আবার চেষ্টা করতে চান? এক্ষেত্রে আমার পুনর্নির্বাচন একটি রিপ্লে কেবল পঠন মডেলটির অবস্থা পুনরুদ্ধার করে না তবে বাহ্যিক ঘটনাও ঘটায়, এটিকে কি ন্যায্য মনে হচ্ছে বা আমি কিছু অনুপস্থিত করছি?
জাস

2
@ জাস: আপনি ব্যর্থ বহিরাগত সিস্টেম কলটির পুনরায় চেষ্টা করতে "পুনরায় খেলুন" এর অপব্যবহার করতে চান না। আপনি নিজের সিস্টেমের পড়ার মডেলটি আগের অবস্থায় একই অবস্থায় পাওয়ার জন্য আপনি "রিপ্লে" ব্যবহার করেন। এর অর্থ ব্যর্থ শিপিংয়ের অনুরোধের ক্ষেত্রে, আপনার সিস্টেমটিকে এই ব্যর্থতা সম্পর্কে আগে অবহিত করা হয়েছিল এবং সেই তথ্যটি তার রাজ্যের কোথাও সংরক্ষণ করেছিল। রিপ্লে নিশ্চিত করে যে এই তথ্য এখনও "পুনরায় প্রচার ও পুনরায় খেলুন" এর আগে রয়েছে। সুতরাং রিপ্লেয়ের পরে আপনার সিস্টেমে "ব্যর্থতার ক্ষেত্রে পুনরায় চেষ্টা করা শিপিং" কৌশল প্রয়োগ করতে পারে (যার সিকিউআরএসের সাথে কোনও সম্পর্ক নেই, যে কোনও শক্তিশালী ক্রমবর্ধমান সিস্টেমে ঠিক এমন কৌশল থাকা উচিত)।
ডক ব্রাউন

মজার বিষয় হচ্ছে, আমি যা করতে চাইছিলাম তা অবাক করেই ভাবছিলাম, যদি এর উপর কোনও "প্যাটার্ন" থাকে তবে আমি চক্রটিকে পুনরায় উদ্দীপনা না দেই!
জাস

3

মার্টিন ফোলারের ইভেন্ট স্যুরসিং নিবন্ধ থেকে:

ইভেন্ট সোর্সিংয়ের মৌলিক ধারণাটি হ'ল যে কোনও অ্যাপ্লিকেশনের স্থিতির প্রতিটি পরিবর্তনকে কোনও ইভেন্ট অবজেক্টে বন্দী করা হয়েছে, এবং এই ইভেন্টের বিষয়গুলি সেগুলি নিজেরাই সেই ক্রমটিতে সংরক্ষিত থাকে যেগুলি প্রয়োগের রাষ্ট্র হিসাবে একই আজীবনের জন্য প্রয়োগ করা হয়েছিল।

সুতরাং যখন আপনাকে আপনার সিস্টেমের স্থিতি একটি নির্দিষ্ট মুহুর্তে পুনরুদ্ধার করতে হবে তখন আপনি সেই মুহুর্ত অবধি ইভেন্ট হ্যান্ডলারদের নয়, সঞ্চিত রাজ্যের পুনরায় খেলুন।

বলা হচ্ছে, আপনি যদি কেবলমাত্র রাষ্ট্রীয় ডেটা নিয়ে কাজ করেন তবে বাহ্যিক সিস্টেমে কোনও প্রভাব থাকতে হবে না। আপনার ইভেন্ট স্টোরে যদি ট্রিগার বা নজরদার না থাকে তবে যদি না আপনি পুনরুদ্ধারের সময়কালের জন্য তাদের অক্ষম করতে পারেন। যেহেতু আপনি বলেছেন যে বাহ্যিক সিস্টেমে আপনার নিয়ন্ত্রণ নেই সেখানে উন্মুক্ত এপিআই ব্যবহার করে এর রাজ্য পুনরুদ্ধার করার কোনও প্রচেষ্টা করা উচিত নয় কারণ আপনি জানেন না যে তাদের সিস্টেমে এর কী পার্শ্ব প্রতিক্রিয়া থাকতে পারে। পুনরুদ্ধারটি যদি সিস্টেমকে একটি মধ্যবর্তী অবস্থায় রাখে (যেমন: বাহ্যিক সিস্টেমে ব্যর্থ ক্রিয়াকলাপের কারণে) এটি কোনও ইভেন্টের পুনরায় প্লে করার দায়িত্বের মধ্যে পড়ে না।


2

তবে, যদি ইভেন্টগুলির মধ্যে কোনওটি আপনার নিয়ন্ত্রণে থাকা কোনও বাহ্যিক সিস্টেমকে গ্রাহকের কাছে "কোনও জিনিস প্রেরণ" না করার কারণ হয়ে থাকে তবে যদি আপনি কেবল ইভেন্টগুলি পুনরায় খেলুন তবে আইটেমটি দু'বার পাঠানো হবে।

একটি নির্দিষ্ট উদাহরণ চয়ন করতে, আসুন বিবেচনা করুন কীভাবে "অন্তত একবার" পার্শ্ব প্রতিক্রিয়াগুলির দিকে দৃষ্টিভঙ্গি কার্যকর হতে পারে।

State currentState = State.InitialState
for(Event e : events) {
    currentState = currentState.apply(e)
}
for(SideEffect s : currentState.querySideEffects()) {
    performSideEffect(s)

সুতরাং ডোমেন মডেলটি কী করা দরকার তা ট্র্যাক করে; কিন্তু অ্যাপ্লিকেশনটিতে আসল কাজটি ছেড়ে দেয়

কমান্ড চালানোর প্রসঙ্গে, প্রাথমিক ধারণাটি একই দেখায়। প্রকৃত পার্শ্ব প্রতিক্রিয়াগুলি লেনদেনের বাইরে ঘটে যা মডেলটিকে আপডেট করে।

সুতরাং আপনার মডেলের জন্য ইউনিট পরীক্ষাগুলি এর মতো দেখতে পারে

{
    // Given
    State currentState = State.InitialState

    // When
    Events events = List.of(OrderPlaced)

    // Then
    List.of(SendEmail) === currentState.applyAll(events).querySideEffects()
}

{
    // Given
    State currentState = State.InitialState

    // When
    Events events = List.of(OrderPlaced, EmailSent)

    // Then
    List.EMPTY === currentState.applyAll(events).querySideEffects()
}

এখানে প্রধান পয়েন্ট

  • মডেল আপডেট করা পার্শ্ব প্রতিক্রিয়া বিনামূল্যে; প্রকৃত পার্শ্ব প্রতিক্রিয়াগুলি লেনদেনের বাইরে ঘটে যা মডেলটিকে আপডেট করে।
  • পার্শ্ব প্রতিক্রিয়ার ফলাফল বর্ণনা করে এমন একটি ইভেন্ট ফিরে আসতে হবে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.