জাভা স্টপ এক্সিকিউটর পরিষেবা একবার তার নির্ধারিত কোনও কাজ কোনও কারণে ব্যর্থ হয়


12

আমার এমন একধরণের পরিষেবা প্রয়োজন যা একসাথে কয়েকটি কাজ চালাবে এবং 1 মিনিটের জন্য 1 সেকেন্ডের ব্যবধানে।

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

উদাহরণস্বরূপ, আমার 2 টি ফাংশন রয়েছে:

Runnable task1 = ()->{
      int num = Math.rand(1,100);
      if (num < 5){
          throw new Exception("something went wrong with this task,terminate");
      }
}

Runnable task2 = ()->{
      int num = Math.rand(1,100)
      return num < 50;
}



ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
task1schedule = scheduledExecutorService.scheduleAtFixedRate(task1, 1, 60, TimeUnit.SECONDS);
task2schedule = scheduledExecutorService.scheduleAtFixedRate(task2, 1, 60, TimeUnit.SECONDS);

if (!task1schedule || !task2schedule) scheduledExecutorService.shutdown();

কীভাবে আমার এটিকে মোকাবেলা করা উচিত এবং জিনিসগুলি যতটা সম্ভব জেনারিক করা উচিত?


1
আসল প্রশ্ন বাদে কয়েকটি জিনিস, Math.randকোনও বিল্ট-ইন এপিআই নয়। একটি বাস্তবায়ন Runnableএকটি void runসংজ্ঞা থাকতে হবে । প্রকার task1/2scheduleহবে ScheduledFuture<?>প্রদত্ত প্রেক্ষাপটে। আসল প্রশ্নে সরানো, কীভাবে এটি ব্যবহার করতে ঘুরতে যায় awaitTermination? আপনি যে হিসাবে করতে পারে scheduledExecutorService.awaitTermination(1,TimeUnit.MINUTES);। বিকল্পভাবে, কোনও কাজ এর সাধারণ সমাপ্তির আগে বাতিল হয়ে গেছে কিনা তা যাচাইয়ের বিষয়ে কী if (task1schedule.isCancelled() || task2schedule.isCancelled()) scheduledExecutorService.shutdown();?
নামান

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

উত্তর:


8

ধারণাটি হ'ল কাজগুলি একটি সাধারণ অবজেক্টের দিকে এগিয়ে চলেছে TaskCompleteEvent। যদি তারা কোনও ত্রুটি ঠেলে তফসিলকারী বন্ধ হয়ে যায় এবং সমস্ত কাজ বন্ধ হয়ে যায়।

আপনি মানচিত্র "ত্রুটি" এবং "সাফল্য" এর প্রতিটি কার্য-পুনরাবৃত্তির ফলাফলগুলি পরীক্ষা করতে পারেন।

public class SchedulerTest {

    @Test
    public void scheduler() throws InterruptedException {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
        TaskCompleteEvent taskCompleteEvent = new TaskCompleteEvent(scheduledExecutorService);
        Runnable task1 = () -> {
            int num = new Random().nextInt(100);
            if (num < 5) {
                taskCompleteEvent.message("task1-"+UUID.randomUUID().toString(), "Num "+num+" was obatined. Breaking all the executions.", true);
            }
        };
        Runnable task2 = () -> {
            int num = new Random().nextInt(100);
            taskCompleteEvent.message("task2-"+UUID.randomUUID().toString(), num < 50, false);
        };
        scheduledExecutorService.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS);
        scheduledExecutorService.scheduleAtFixedRate(task2, 0, 1, TimeUnit.SECONDS);
        scheduledExecutorService.awaitTermination(60, TimeUnit.SECONDS);
        System.out.println("Success: "+taskCompleteEvent.getSuccess());
        System.out.println("Errors: "+taskCompleteEvent.getErrors());
        System.out.println("Went well?: "+taskCompleteEvent.getErrors().isEmpty());
    }

    public static class TaskCompleteEvent {

        private final ScheduledExecutorService scheduledExecutorService;
        private final Map<String, Object> errors = new LinkedHashMap<>();
        private final Map<String, Object> success = new LinkedHashMap<>();

        public TaskCompleteEvent(ScheduledExecutorService scheduledExecutorService) {
            this.scheduledExecutorService = scheduledExecutorService;
        }

        public synchronized void message(String id, Object response, boolean error) {
            if (error) {
                errors.put(id, response);
                scheduledExecutorService.shutdown();
            } else {
                success.put(id, response);
            }
        }

        public synchronized Map<String, Object> getErrors() {
            return errors;
        }

        public synchronized Map<String, Object> getSuccess() {
            return success;
        }

    }

}

2

আপনাকে কেবল একটি অতিরিক্ত টাস্ক যুক্ত করতে হবে যার কাজ অন্যান্য চলমান সমস্ত কার্য নিরীক্ষণ করা - এবং যখন তদারকি করা কোনও কাজ ব্যর্থ হয় তখন তাদের একটি সেমফোর (পতাকা) নির্ধারণ করা প্রয়োজন যা ঘাতক তদন্ত করতে পারে।

    ScheduledExecutorService executor = (ScheduledExecutorService) Executors.newScheduledThreadPool(2);

    // INSTANTIATE THE REMOTE-FILE-MONITOR:
    RemoteFileMonitor monitor = new RemoteFileMonitor(remotesource, localtarget);

    // THIS TimerTask PERIODICALLY TRIGGERS THE RemoteFileMonitor: 
    TimerTask remote = new TimerTask() {

        // RUN FORREST... RUN !
        public void run() {

            try { 

                kae.trace("TimerTask::run() --> Calling RemoteFileMonitor.check()");
                monitor.check();

            } catch (Exception ex) {

                // NULL TRAP: ALLOWS US TO CONTINUE AND RETRY:

            }

        }

    };

    // THIS TimerTask PERIODICALLY TRIES TO KILL THE REMOTE-FILE-MONITOR:
    TimerTask assassin = new TimerTask() {

        // WHERE DO BAD FOLKS GO WHEN THEY DIE ? 
        private final LocalDateTime death = LocalDateTime.now().plus(ConfigurationOptions.getPollingCycleTime(), ChronoUnit.MINUTES);

        // RUN FORREST... RUN !
        public void run() {

            // IS THERE LIFE AFTER DEATH ???
            if (LocalDateTime.now().isAfter(death)) {

                // THEY GO TO A LAKE OF FIRE AND FRY:
                kae.error(ReturnCode.MONITOR_POLLING_CYCLE_EXCEEDED);                   

            }

        }

    };

    // SCHEDULE THE PERIODIC EXECUTION OF THE RemoteFileMonitor: (remote --> run() monitor --> check())
    executor.scheduleAtFixedRate(remote, delay, interval, TimeUnit.MINUTES);

    // SCHEDULE PERIODIC ASSASSINATION ATTEMPTS AGAINST THE RemoteFileMonitor: (assassin --> run() --> after death --> die())
    executor.scheduleAtFixedRate(assassin, delay, 60L, TimeUnit.SECONDS);

    // LOOP UNTIL THE MONITOR COMPLETES:
    do {

        try {

            // I THINK I NEED A NAP:
            Thread.sleep(interval * 10);                

        } catch (InterruptedException e) {

            // FAIL && THEN cleanexit();
            kae.error(ReturnCode.MONITORING_ERROR, "Monitoring of the XXXXXX-Ingestion site was interrupted");

        }

        // NOTE: THE MONITOR IS SET TO 'FINISHED' WHEN THE DONE-File IS DELIVERED AND RETRIEVED:
    } while (monitor.isNotFinished());

    // SHUTDOWN THE MONITOR TASK:
    executor.shutdown();

2
বর্গটি TimerTaskসম্পূর্ণরূপে সম্পর্কিত নয় ScheduledExecutorService; এটি বাস্তবায়নের জন্যই ঘটে Runnable। তদুপরি, একটি নির্দিষ্ট সময় ( ConfigurationOptions.getPollingCycleTime()) পৌঁছেছে কিনা তা খতিয়ে দেখার জন্য পর্যায়ক্রমে কোনও কার্যক্রমে নির্ধারিত করার কোনও মানে হয় না । আপনার কাছে একটি রয়েছে ScheduledExecutorService, তাই আপনি পছন্দসই সময়ের জন্য সঠিক সময় নির্ধারণ করতে বলতে পারেন।
হলগার

আমি যে উদাহরণটি ব্যবহার করেছি তা বাস্তবায়ন হ'ল যদি কাজটি শেষ না হয় তবে নির্দিষ্ট সময়ের পরে একটি নির্বাহক টাস্ককে হত্যা করা। ব্যবহারের কেসটি ছিল: যদি দূরবর্তী সার্ভারটি ২৪ ঘন্টার মধ্যে কোনও ফাইল না ফেলে থাকে তবে কাজটি শেষ করে দিন। এটিই ওপি চেয়েছিল।
গ্রেগ প্যাটনুড

আপনি আমার মন্তব্য পড়া এবং বুঝতে পেরেছি? কোডটি যা করে তা বিবেচ্য নয়, এটি বিনা কারণে নিরুৎসাহিত ক্লাস ব্যবহার করে, কেবল এটির TimerTaskসাথে প্রতিস্থাপন করুন Runnableএবং কোডটি কী করে তা পরিবর্তন না করেই আপনি সমস্যার সমাধান করেছেন। আরও, কেবল ব্যবহার করুন executor.schedule(assassin, ConfigurationOptions.getPollingCycleTime(), ChronoUnit.MINUTES);এবং এটি পছন্দসই সময়ে একবার চলবে, সুতরাং, if(LocalDateTime.now().isAfter(death))চেকটি অপ্রচলিত। আবার কোডটি কী করে তা পরিবর্তিত করে না, এটিকে যথেষ্ট সহজ এবং আরও দক্ষ করে তোলা।
হলগার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.