2009-07-14 9 views
6

Ho una funzione di indicizzazione denominata "Execute()" che utilizza IndexWriter per indicizzare il contenuto del mio sito. Funziona alla grande se l'ho chiamato semplicemente da una pagina web, ma non è riuscito quando lo ho come parametro delegato in System.Threading.Thread. Stranamente però, funziona sempre sulla mia macchina dev locale, fallisce solo quando carico su un host condiviso.Issue.Net e problema di threading I/O

Questo è il messaggio di errore ho ottenuto

"Blocco ottenere scaduta: errore di SimpleFSLock ...."

Di seguito si riporta il codice fallito (ma non solo su un host condiviso)

Scheduler scheduler = new Scheduler(); 
System.Threading.Thread schedulerThread = new System.Threading.Thread(scheduler.Execute); 

di seguito è il codice che funziona (il lavoro sia sulla mia macchina locale e su host condiviso)

Scheduler scheduler = new Scheduler(); 
schedulre.Execute(); 

Ora, alcuni ppl detto, potrebbe essere una cattiva lasciati dal precedente sessione di debug, quindi prima ho istanziati l'IndexWriter, ho fatto

if (IndexReader.IsLocked(indexingFolder)) 
{ 

    log.Debug("it is locked"); 
    IndexReader.Unlock(FSDirectory.GetDirectory(indexingFolder)); 
} 
else 
{ 
    log.Debug("it is not locked"); 
} 

e indovinate un po? il mio registro dice, non è bloccato.

Quindi ora sono abbastanza sicuro che sia causato dal System.Thread.Threading, ma non ho idea di come ripararlo.

Grazie

+0

Ho aggiornato la mia risposta per incorporare ciò che hai chiesto nel tuo commento. –

risposta

0

Probabilmente il peggiore per cercare di rispondere a questa visto che non ho usato Lucene/hosting condiviso, ma SimpleFSLock suona come sta bloccando il file di indice Lucene utilizzando un file di blocco esplicito nel file system (non proprio come il blocco nella filettatura). Direi di controllare per essere sicuri di aver configurato i percorsi dei file corretti e che i permessi dei file siano impostati correttamente.

Altrimenti, si spera che qualcuno più familiare con Lucene.net possa rispondere.

+0

Grazie Kevin. I percorsi dei file sono corretti perché se eseguo semplicemente la funzione non coinvolgendo il threading, tutto funziona come previsto, gli indici vengono creati e sono in grado di cercare tutti i contenuti. Non appena passo la funzione nel costruttore di Thread(), esplode. ps: grazie per avermi aiutato nella formattazione :) –

4

Verificare che sull'host condiviso, il thread disponga delle stesse autorizzazioni per la cartella dell'indice come sul computer di sviluppo/host condiviso.

Aggiornamento: È possibile trovare ciò che Principal il filo è in esecuzione con interrogando proprietà del thread CurrentPrincipal. Sebbene si tratti di una proprietà di lettura-scrittura, è possibile che non si disponga delle autorizzazioni per impostare questa proprietà nel proprio ambiente host condiviso.

Potresti trovare utile this post.

+0

Ehi Vinay, come faccio a verificare se un thread ha lo stesso permesso di me? –

0

Credo che il problema sia con un file di blocco di scrittura nella directory dell'indice di Lucene. Vai ed elenca i file della directory. In Java Lucene, avresti visto un file denominato write.lock nella directory dell'indice, , il che significa che l'indice non è stato chiuso correttamente l'ultima volta (forse un processo è stato interrotto bruscamente). In Lucene.net, cerca un file vuoto con lo stesso nome. Credo che lo stesso meccanismo verrà utilizzato in Lucene.net. Prova a trovare quel file, cancellandolo e riavviando Lucene.net.

+0

Grazie Yuval. Ho appena eseguito uno script e stampe segments.gen segments_6 _1.cfs Questo è tutto. Il dettaglio del messaggio di errore indica effettivamente il problema con "write.lock" nella mia directory di indicizzazione. Tuttavia, come il risultato dello script mostrato sopra, non esiste alcun file "write.lock". –

2

Grazie a tutti e soprattutto a Vinay per avermi indicato nella giusta direzione. Dopo molte tracce, alla fine ho deciso di dare un'occhiata alla fonte e vedere cosa c'è.

In "IndexWriter", avete

Lock @lock = this.directory.MakeLock("write.lock"); 
    if ([email protected](this.writeLockTimeout)) 

che è puntato alla realizzazione SimpleFSLock. Il colpevole era

new FileStream(this.lockFile.FullName, FileMode.CreateNew).Close(); 

creando un nuovo filo, internamente, si getta una System.UnauthorizedAccessException, secondo MSDN here

Quando si inizia un nuovo filo, System.Security.Principal.WindowsIdentity.GetCurrent() restituisce l'identità del processo, non necessariamente l'identità del codice che ha chiamato Thread.Start(). È importante ricordare quando si avviano i delegati asincroni o i thread in un thread ASP.NET rappresentato.

Se si è in ASP.NET e si desidera che il nuovo thread inizi con WindowsIdentity impersonato, passare WindowsIdentity al metodo ThreadStart. Una volta nel metodo ThreadStart, chiama WindowsIdentity.Impersonate().

Tale, ho risolto il mio problema impersonando l'account IIS che esegue la mia applicazione nella funzione "Execute()" e tutti i problemi sono stati risolti.

Grazie ancora a tutti.

+0

Bene, il modo normale di mostrare i tuoi ringraziamenti è di andare avanti e/o accettare la risposta :-) –