S
spoofs
Gast
Hallo allerseits,
cih brüte schon eine ganze Weile über einem Problem bei meiner Webanwendung. Und zwar soll der Benutzer bestimmte Dateien über einen Cache abgreifen können, diese Dateien müssen aber erst generiert werden. Das ganze läuft so ab dass bei einer Anfrage geguckt wird ob die Datei bereits im Cache liegt, wenn ja dann benutzte sie, sonst generiere sie und packe sie in den Cache und benutze sie dann.
Mein Problem liegt nun darin das das Generieren der Datei ca. 2-3 Sekunden dauert. Sprich der erste Benutzter fordert die Datei an -> sieht sie liegt nicht im Speicher und beginnt mit der Generierung, welche mit dem Speichern im Cache endet. In der Zwischenzeit (während die erste Anfrage noch am generieren ist) kommt eine zweite Anfrage DIESELBE Datei zu abzugreifen. Es wird in den Cache geguckt ob die Datei da ist (ist sie natürlich noch nicht weil der erste noch am generieren ist) und so beginnt der zweite dieselbe Datei zu generieren und die vom ersten geschriebenen zu überbügeln.
In der Zwischenzeit will der erste (der ja weiß das die Datei im Cache ist, weil er die gerade selber da reingepackt hat) die Datei weilterbenutzten bekommt jetzt aber irgendeinen unvollständigen Müll weil der zweite gerade rausschreibt.
So nun mal zu der Methode: Sie hat als Parameter nur die Dateinamen (Inputfiles und das Resultfile) als String. Achtung: daran kann ich auch nichts ändern! Das muß so bleiben.
Pseudo läuft das ganze so ab:
Ich kann das Problem umgehen wenn ich die Methode synchronized setzte. Das hieße aber das alle Anfragen (egal welche Datei) warten müßten, bis die vorherigen fertig sind. Das wird unter Last aber nicht funktionieren und das Ganze wahnsinnig langsam machen.
Deswegen würde ich gerne den Inhalt der Methode abhängig vom übergebenen "result"-Filenamen synchronisieren.
Ich hab das ganze mal probeweise so umgesetzt:
Da ich mit Synchronisierung aber noch nichts gemacht habe weiß ich nicht ob das so geht bzw. ich bezweifele das das optimal ist (obwohl es funktioniert), denn muß ich dann nicht auch den Zugriff auf lockedFiles synchronisieren? Und habe ich dann nicht das selbe Problem das alle warten müssen bis lockedFiles wieder freigegeben wird?
Ich weiß echt nicht wie ich das umsetzten soll, ich kann kaum was ändern am vorhandenen Code. Das die Generierung der Datei 2-3 Sekunden dauert ist normal, da es ein mehrstufiger komplexer Prozeß ist bevor die Datei rausgeschrieben werden kann. Ist es nicht irgendwie möglich die Methode bezogen auf den resulfile-Namen zu sperren und entsperren?
Hoffe ihr habt ein paar vorschläge für mich, brüte da schon ne ganze Weile drüber. Im Prinzip müßte ich mir global merken welche Dateien gerade geprüft/generiert werden und dementsprechend bei Doppelanfragen sperren oder freigeben. Das ist ja das was ich da oben mikt meinem Ansatz versuche aber ich weiß nicht ob das sinnvoll ist, bzw ob es besser geht.
Danke für die Geduld,
spoofs
cih brüte schon eine ganze Weile über einem Problem bei meiner Webanwendung. Und zwar soll der Benutzer bestimmte Dateien über einen Cache abgreifen können, diese Dateien müssen aber erst generiert werden. Das ganze läuft so ab dass bei einer Anfrage geguckt wird ob die Datei bereits im Cache liegt, wenn ja dann benutzte sie, sonst generiere sie und packe sie in den Cache und benutze sie dann.
Mein Problem liegt nun darin das das Generieren der Datei ca. 2-3 Sekunden dauert. Sprich der erste Benutzter fordert die Datei an -> sieht sie liegt nicht im Speicher und beginnt mit der Generierung, welche mit dem Speichern im Cache endet. In der Zwischenzeit (während die erste Anfrage noch am generieren ist) kommt eine zweite Anfrage DIESELBE Datei zu abzugreifen. Es wird in den Cache geguckt ob die Datei da ist (ist sie natürlich noch nicht weil der erste noch am generieren ist) und so beginnt der zweite dieselbe Datei zu generieren und die vom ersten geschriebenen zu überbügeln.
In der Zwischenzeit will der erste (der ja weiß das die Datei im Cache ist, weil er die gerade selber da reingepackt hat) die Datei weilterbenutzten bekommt jetzt aber irgendeinen unvollständigen Müll weil der zweite gerade rausschreibt.
So nun mal zu der Methode: Sie hat als Parameter nur die Dateinamen (Inputfiles und das Resultfile) als String. Achtung: daran kann ich auch nichts ändern! Das muß so bleiben.
Pseudo läuft das ganze so ab:
Code:
public static void generateAndCacheFile(String infile1, String infile2, String resultfile){
if(!isCached(resultfile)){
//starte mit dem generieren
generateFile(infile1,infile2,resultfile);
}
}
Ich kann das Problem umgehen wenn ich die Methode synchronized setzte. Das hieße aber das alle Anfragen (egal welche Datei) warten müßten, bis die vorherigen fertig sind. Das wird unter Last aber nicht funktionieren und das Ganze wahnsinnig langsam machen.
Deswegen würde ich gerne den Inhalt der Methode abhängig vom übergebenen "result"-Filenamen synchronisieren.
Ich hab das ganze mal probeweise so umgesetzt:
Code:
private static Arraylist lockedFilenames;
...
public static void generateAndCacheFile(String infile1, String infile2, String resultfile){
while(lockedFilenames.contains(resultfile)){
//warte einfach
}
lockedFilenames.add(resultfile); //Dateinamen sperren
if(!isCached(resultfile)){
//starte mit dem generieren
generateFile(infile1,infile2,resultfile);
}
lockedFilenames.remove(resultfile); //Dateinamen wieder freigeben
}
Da ich mit Synchronisierung aber noch nichts gemacht habe weiß ich nicht ob das so geht bzw. ich bezweifele das das optimal ist (obwohl es funktioniert), denn muß ich dann nicht auch den Zugriff auf lockedFiles synchronisieren? Und habe ich dann nicht das selbe Problem das alle warten müssen bis lockedFiles wieder freigegeben wird?
Ich weiß echt nicht wie ich das umsetzten soll, ich kann kaum was ändern am vorhandenen Code. Das die Generierung der Datei 2-3 Sekunden dauert ist normal, da es ein mehrstufiger komplexer Prozeß ist bevor die Datei rausgeschrieben werden kann. Ist es nicht irgendwie möglich die Methode bezogen auf den resulfile-Namen zu sperren und entsperren?
Hoffe ihr habt ein paar vorschläge für mich, brüte da schon ne ganze Weile drüber. Im Prinzip müßte ich mir global merken welche Dateien gerade geprüft/generiert werden und dementsprechend bei Doppelanfragen sperren oder freigeben. Das ist ja das was ich da oben mikt meinem Ansatz versuche aber ich weiß nicht ob das sinnvoll ist, bzw ob es besser geht.
Danke für die Geduld,
spoofs