Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(developer): create Server config directory before options save 🍒 🏠 #12609

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 37 additions & 30 deletions developer/src/tike/main/KeymanDeveloperOptions.pas
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ TKeymanDeveloperOptions = class
procedure optWriteInt(const nm: string; value: Integer);
procedure WriteServerConfigurationJson;
class function Default_DefaultProjectPath: string; static;
function BackOffAndSaveJson(const Filename: string; const JSON: TJSONObject): Boolean;
public
procedure Read;
procedure Write;
Expand Down Expand Up @@ -406,8 +407,6 @@ procedure TKeymanDeveloperOptions.Read;
end;

procedure TKeymanDeveloperOptions.Write;
var
count: Integer;
begin
// If the output file does not exist, this creates it. Note that we load
// from the existing file before writing out our set of options, which is
Expand Down Expand Up @@ -464,33 +463,7 @@ procedure TKeymanDeveloperOptions.Write;
ForceDirectories(TKeymanDeveloperPaths.OptionsPath);

try
count := 0;
repeat
try
SaveJSONToFile(TKeymanDeveloperPaths.OptionsPath + TKeymanDeveloperPaths.S_OptionsJson, json);
Break;
except
on E:EOSError do
begin
if E.ErrorCode = ERROR_ACCESS_DENIED then
begin
// Back off and retry 0.5 sec later, it's probably another
// instance happening to read or write the settings file
Inc(count);
Sleep(500);
end
else
raise;
end
else
raise;
end;
until count >= Max_Retries;
if count >= Max_Retries then
begin
if TKeymanSentryClient.Instance <> nil then
TKeymanSentryClient.Instance.ReportMessage('TKeymanDeveloperOptions: Failed to write settings after 5 tries');
end;
BackOffAndSaveJson(TKeymanDeveloperPaths.OptionsPath + TKeymanDeveloperPaths.S_OptionsJson, json);
except
on E:Exception do
begin
Expand All @@ -507,6 +480,39 @@ procedure TKeymanDeveloperOptions.Write;
WriteServerConfigurationJson;
end;

function TKeymanDeveloperOptions.BackOffAndSaveJson(const Filename: string; const JSON: TJSONObject): Boolean;
var
count: Integer;
begin
count := 0;
repeat
try
SaveJSONToFile(Filename, JSON);
Exit(True);
except
on E:EOSError do
begin
if E.ErrorCode = ERROR_ACCESS_DENIED then
begin
// Back off and retry 0.5 sec later, it's probably another
// instance happening to read or write the settings file
Inc(count);
Sleep(500);
end
else
raise;
end
else
raise;
end;
until count >= Max_Retries;

if TKeymanSentryClient.Instance <> nil then
TKeymanSentryClient.Instance.ReportMessage('TKeymanDeveloperOptions: Failed to write '+Filename+' after 5 tries');

Result := False;
end;

procedure TKeymanDeveloperOptions.WriteServerConfigurationJson;
var
o: TJSONObject;
Expand All @@ -517,7 +523,8 @@ procedure TKeymanDeveloperOptions.WriteServerConfigurationJson;
o.AddPair('ngrokToken', FServerNgrokToken);
o.AddPair('useNgrok', TJSONBool.Create(FServerUseNgrok));
o.AddPair('ngrokVisible', TJSONBool.Create(FServerServerShowConsoleWindow));
SaveJSONToFile(TKeymanDeveloperPaths.ServerDataPath + TKeymanDeveloperPaths.S_ServerConfigJson, o);
ForceDirectories(TKeymanDeveloperPaths.ServerDataPath);
BackOffAndSaveJSON(TKeymanDeveloperPaths.ServerDataPath + TKeymanDeveloperPaths.S_ServerConfigJson, o);
finally
o.Free;
end;
Expand Down
Loading