Skip to content

Adding github dev button #194

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

Open
wants to merge 13 commits into
base: dev-react
Choose a base branch
from
212 changes: 106 additions & 106 deletions ServerlessLibraryAPI/CacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,127 +9,127 @@

namespace ServerlessLibrary
{
public interface ICacheService
public interface ICacheService
{
IList<LibraryItemWithStats> GetCachedItems();
}

//https://stackoverflow.com/questions/44723017/in-memory-caching-with-auto-regeneration-on-asp-net-core
public class CacheService : ICacheService
{
protected readonly IMemoryCache _cache;
private readonly ILibraryStore libraryStore;
private readonly ILogger logger;

private Task LoadingTask = Task.CompletedTask;
private Timer Timer = null;
private bool LoadingBusy = false;
private bool isCacheLoadedOnce = false;

public CacheService(IMemoryCache cache, ILibraryStore libraryStore, ILogger<CacheService> logger)
{
IList<LibraryItemWithStats> GetCachedItems();
this._cache = cache;
this.libraryStore = libraryStore;
this.logger = logger;
InitTimer();
}

//https://stackoverflow.com/questions/44723017/in-memory-caching-with-auto-regeneration-on-asp-net-core
public class CacheService : ICacheService
private void InitTimer()
{
protected readonly IMemoryCache _cache;
private readonly ILibraryStore libraryStore;
private readonly ILogger logger;
_cache.Set<LibraryItemsResult>(ServerlessLibrarySettings.CACHE_ENTRY, new LibraryItemsResult() { Result = new List<LibraryItemWithStats>(), IsBusy = true });

private Task LoadingTask = Task.CompletedTask;
private Timer Timer = null;
private bool LoadingBusy = false;
private bool isCacheLoadedOnce = false;

public CacheService(IMemoryCache cache, ILibraryStore libraryStore, ILogger<CacheService> logger)
{
this._cache = cache;
this.libraryStore = libraryStore;
this.logger = logger;
InitTimer();
}
Timer = new Timer(TimerTickAsync, null, 1000, ServerlessLibrarySettings.SLCacheRefreshIntervalInSeconds * 1000);
}

private void InitTimer()
public IList<LibraryItemWithStats> GetCachedItems()
{
// Make a blocking call to load cache on first time call.
if (!isCacheLoadedOnce)
{
try
{
_cache.Set<LibraryItemsResult>(ServerlessLibrarySettings.CACHE_ENTRY, new LibraryItemsResult() { Result = new List<LibraryItemWithStats>(), IsBusy = true });

Timer = new Timer(TimerTickAsync, null, 1000, ServerlessLibrarySettings.SLCacheRefreshIntervalInSeconds * 1000);
logger.LogInformation("Loading initial cache");
IList<LibraryItemWithStats> items = this.ConstructCache().Result;
_cache.Set(ServerlessLibrarySettings.CACHE_ENTRY, new LibraryItemsResult() { Result = items, IsBusy = false });
logger.LogInformation("Loaded {0} items into cache", items.Count());
}

public IList<LibraryItemWithStats> GetCachedItems()
catch (Exception ex)
{
// Make a blocking call to load cache on first time call.
if (!isCacheLoadedOnce)
{
try
{
logger.LogInformation("Loading initial cache");
IList<LibraryItemWithStats> items = this.ConstructCache().Result;
_cache.Set(ServerlessLibrarySettings.CACHE_ENTRY, new LibraryItemsResult() { Result = items, IsBusy = false });
logger.LogInformation("Loaded {0} items into cache", items.Count());
}
catch (Exception ex)
{
this.logger.LogError(ex, "Failed to load cache in first call");
}
}

logger.LogInformation("Successfully loaded initial cache");
isCacheLoadedOnce = true;
return _cache.Get<LibraryItemsResult>(ServerlessLibrarySettings.CACHE_ENTRY).Result;
this.logger.LogError(ex, "Failed to load cache in first call");
}
}

private async void TimerTickAsync(object state)
{
logger.LogInformation("Cache refresh timer fired");
if (!isCacheLoadedOnce || LoadingBusy)
{
logger.LogWarning("Skipping cache refresh");
return;
}
logger.LogInformation("Successfully loaded initial cache");
isCacheLoadedOnce = true;
return _cache.Get<LibraryItemsResult>(ServerlessLibrarySettings.CACHE_ENTRY).Result;
}

try
{
LoadingBusy = true;
LoadingTask = LoadCaches();
await LoadingTask;
}
catch
{
// do not crash the app
}
finally
{
LoadingBusy = false;
}
}
private async Task LoadCaches()
{
try
{
logger.LogInformation("Starting cache refresh");
var items = await ConstructCache();
_cache.Set<LibraryItemsResult>(ServerlessLibrarySettings.CACHE_ENTRY, new LibraryItemsResult() { Result = items, IsBusy = false });
logger.LogInformation("Updated cache with {0} items", items.Count());
}
catch (Exception ex)
{
this.logger.LogError(ex, "Failed to load cache");
}
}
private async Task<IList<LibraryItemWithStats>> ConstructCache()
{
logger.LogInformation("Starting ConstructCache");
IList<LibraryItem> libraryItems;
IList<LibraryItemWithStats> libraryItemsWithStats = new List<LibraryItemWithStats>();
libraryItems = await this.libraryStore.GetAllItems();
logger.LogInformation("Cosmos DB returned {0} results", libraryItems.Count());
var stats = await StorageHelper.getSLItemRecordsAsync();
logger.LogInformation("Storage returned {0} results", stats.Count());
foreach (var storeItem in libraryItems)
{
var item = storeItem.ConvertTo<LibraryItemWithStats>();
var itemStat = stats.Where(s => s.id == storeItem.Id.ToString()).FirstOrDefault();
item.TotalDownloads = itemStat != null && itemStat.totalDownloads > 0 ? itemStat.totalDownloads : 1;
item.Likes = itemStat != null && itemStat.likes > 0 ? itemStat.likes : 0;
item.Dislikes = itemStat != null && itemStat.dislikes > 0 ? itemStat.dislikes : 0;
libraryItemsWithStats.Add(item);
}
private async void TimerTickAsync(object state)
{
logger.LogInformation("Cache refresh timer fired");
if (!isCacheLoadedOnce || LoadingBusy)
{
logger.LogWarning("Skipping cache refresh");
return;
}

logger.LogInformation("ConstructCache returned {0} items", libraryItemsWithStats.Count());
return libraryItemsWithStats;
}
try
{
LoadingBusy = true;
LoadingTask = LoadCaches();
await LoadingTask;
}
catch
{
// do not crash the app
}
finally
{
LoadingBusy = false;
}
}

public class LibraryItemsResult
private async Task LoadCaches()
{
try
{
logger.LogInformation("Starting cache refresh");
var items = await ConstructCache();
_cache.Set<LibraryItemsResult>(ServerlessLibrarySettings.CACHE_ENTRY, new LibraryItemsResult() { Result = items, IsBusy = false });
logger.LogInformation("Updated cache with {0} items", items.Count());
}
catch (Exception ex)
{
this.logger.LogError(ex, "Failed to load cache");
}
}
private async Task<IList<LibraryItemWithStats>> ConstructCache()
{
public IList<LibraryItemWithStats> Result { get; set; }
public bool IsBusy { get; set; }
logger.LogInformation("Starting ConstructCache");
IList<LibraryItem> libraryItems;
IList<LibraryItemWithStats> libraryItemsWithStats = new List<LibraryItemWithStats>();
libraryItems = await this.libraryStore.GetAllItems();
logger.LogInformation("Cosmos DB returned {0} results", libraryItems.Count());
var stats = await StorageHelper.getSLItemRecordsAsync();
logger.LogInformation("Storage returned {0} results", stats.Count());
foreach (var storeItem in libraryItems)
{
var item = storeItem.ConvertTo<LibraryItemWithStats>();
var itemStat = stats.Where(s => s.id == storeItem.Id.ToString()).FirstOrDefault();
item.TotalDownloads = itemStat != null && itemStat.totalDownloads > 0 ? itemStat.totalDownloads : 1;
item.Likes = itemStat != null && itemStat.likes > 0 ? itemStat.likes : 0;
item.Dislikes = itemStat != null && itemStat.dislikes > 0 ? itemStat.dislikes : 0;
libraryItemsWithStats.Add(item);
}

logger.LogInformation("ConstructCache returned {0} items", libraryItemsWithStats.Count());
return libraryItemsWithStats;
}
}

public class LibraryItemsResult
{
public IList<LibraryItemWithStats> Result { get; set; }
public bool IsBusy { get; set; }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,24 @@ class ActionBar extends Component {
return "vscode://vscode.git/clone?url=" + encodeURIComponent(repository);
}

getOpenInGithubDevLink(repository) {
if(repository){
return repository.replace("github\.com", "github\.dev");
} else {
return repository;
}
}

openInVSCodeClick() {
this.updateDownloadCount(this.props.id);
this.trackUserActionEvent("/sample/openinvscode");
}

openInGithubDevClick() {
this.updateDownloadCount(this.props.id);
this.trackUserActionEvent("/sample/openingithubdev");
}

trackUserActionEvent(eventName) {
let eventData = {
id: this.props.id,
Expand Down Expand Up @@ -76,6 +89,18 @@ class ActionBar extends Component {
</div>
</FabricLink>
</div>
<div className="action-item">
<FabricLink
href={this.getOpenInGithubDevLink(repository)}
disabled={!repository}
onClick={this.openInGithubDevClick}
>
<div className="action-link-wrapper">
<Icon iconName="Edit" className="fabric-icon-link" />
<span className="action-link-text">Edit in GitHub.dev</span>
</div>
</FabricLink>
</div>
<div className="action-item">
<FabricLink
href={this.getDeployLink(template)}
Expand Down Expand Up @@ -107,4 +132,4 @@ class ActionBar extends Component {
}
}

export default ActionBar;
export default ActionBar;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const technologies = [
"Functions 3.x",
"Functions 2.x",
"Functions 1.x",
"Logic Apps",
Expand Down
Loading