2013-05-30 27 views
10

Bu yüzden, kullanıcının yüklediği bir dosyadan büyük miktarda veri almak için ayarlanmış bir servisim var. Dosya işlenirken sitede çalışmaya devam edebilmeyi istiyorum. Bir iş parçacığı oluşturarak bunu başardım. Grails Services içindeki konuları yönetme

Thread.start { 
//work done here 
} 

Şimdi problem ben aynı anda çalışan birden konuları olmasını istemediklerini ortaya çıkar. İşte denedim: Bu, işe yaramıyor. thread.isAlive() her zaman false değerini döndürür. Bunu nasıl başarabileceğime dair bir fikrin var mı?

cevap

15

yerine bir Executor kullanarak ele alacak.

import java.util.concurrent.* 
import javax.annotation.* 

class SomeService { 

ExecutorService executor = Executors.newSingleThreadExecutor() 

def serviceMethod() { 
    executor.execute { 
     //Do work here 
    } 
} 


@PreDestroy 
void shutdown() { 
    executor.shutdownNow() 
} 

} 

görevler peş peşe yürütmek sağlayacaktır bir newSingleThreadExecutor kullanma. Çalışmakta olan bir arka plan görevi varsa, sıradaki görev sıraya alınacak ve çalışan görev bittiğinde başlayacaktır (serviceMethod'un kendisi de hemen geri dönecektir).

Bu eklenti, arka plan görevleriniz için uygun kalıcılık bağlamını (ör. Hazırda Bekletme oturumu) ayarlayacağından, "burada çalışın" ifadeniz GORM veritabanı erişimini içeriyorsa, executor plugin'u düşünebilirsiniz.

+0

O Gorm içeriyor - Yalnızca bir seferde alma çalışmasına bir iş parçacığı istiyorsanız

@Async def reallyLongRunningProcess() { //do some stuff that takes ages } 

, böyle bir şey yapabilirdi. Id sadece bunun için bir eklenti yüklememeyi tercih ediyor. Kullanarak kullanabilir miyim? –

+0

@JamesKleeh 'withTransaction' kullanarak bunu yapmalıdır (en azından hazırda beklemedeyseniz, mongo için konuşamıyorum), ancak yürütücü eklentisi çok hafiftir, bu yüzden elden çıkarmayacağım. –

+0

@JamesKleeh, İhtiyaç duyduğunuz ilgili parçaları https://github.com/basejump/grails-executor/tree/master/src/groovy/grails/plugin/executor adresinde bulabilirsiniz. Ben sadece potansiyel sebat sorunları ile uğraşmaktan kaçınmak için eklenti kullanacağım ... – rimero

2

Bunu yapmanın bir başka yolu Spring'in @Async ek açıklama kullanmaktır.

beans = { 
    xmlns task:"http://www.springframework.org/schema/task" 
    task.'annotation-driven'('proxy-target-class':true, 'mode':'proxy') 
} 

şimdi @Async ile açıklama herhangi bir hizmet yöntemi senkronize çalışacak, örneğin:

aşağıdaki resources.groovy ekle

class MyService { 
    boolean longProcessRunning = false 

    @Async 
    def reallyLongRunningProcess() { 
     if (longProcessRunning) return 

     try { 
      longProcessRunning = true 
      //do some stuff that takes ages 
     } finally { 
      longProcessRunning = false 
     } 
    } 
} 
+0

Cevabı takdir ediyorum, ancak yaptığım gibi bir bayrakla bir değişken oluşturabilirdim. Ben sadece böyle yapmamayı tercih ederim. –