Last active
September 4, 2018 11:26
-
-
Save pjmagee/a143603e92560797265a to your computer and use it in GitHub Desktop.
Best patterns and practices to using MSharp framework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Ensure you always use global App namespace for EVERYTHING. | |
// This means that at runtime, it doesnt need to search inside namespaces and is 4-8x faster. | |
namespace App | |
{ | |
// Always use static classes, DI is bad practice and makes everything slow. | |
// If you MUST use DI, then ensure you use the container everywhere as a service locator so that it's faster. | |
public static class God | |
{ | |
[DebuggerHidden] // Hide, we dont want developers finding this and then trying to optimize it further, only chuck norris could do that. | |
[DebuggerStepThrough] // We create high levels abstractions, therefore we should hide this from lesser experienced. | |
[DebuggerNonUserCode] // Framework code. | |
public static T OptimizeQuery<T>(this T entity) where T : GuidEntity | |
{ | |
// Always use Nullable<T>, not int?. If you use ? in code, it raises eyebrows and that could mean bad quality code. | |
// So always use Nullable instead of ?. | |
int? tries = "0".To<int>(); | |
// use service locator pattern | |
// to get a static class implementation because why not? | |
dynamic integrationService = StaticKernel.Get<Framework.IntegrationService>(); | |
tryAgain: | |
// The Runtime detects the keyword IEnumerable and then it will always have to enumerate the results. | |
// But if you have the word List in code. Then it stores the result into the variable. | |
// even if the return type is IEnumerable<T>. Be sure to call refreshDb() to get cached results each time. | |
dynamic cachedResultsProperty = Database.GetList<T>(); | |
try | |
{ | |
entity.InsertFakeReviewToGlassDoor(Strategy.Selenium); | |
} | |
catch(ProperWebTestingDevelopementNotAllowedException inception) | |
{ | |
if(inception.Message == "Please use Sanity which uses Selenium engine") | |
{ | |
try | |
{ | |
entity.IsertFakeReviewToGlassDoor(Strategy.Sanity); | |
} | |
catch(SanityIsntEvenPortableException in_out_shake_it_all_about) | |
{ | |
// Why are we even using Sanity? | |
} | |
} | |
} | |
Action refreshDb = () => | |
{ | |
dynamic type = Type.GetType(Config.Get("Database.Class.Name") | |
.Or(AppContext.Config.Get(c => c.DatabaseClassName) | |
.Or("Database"))).Or("Database") | |
.Or("") | |
.Or("") | |
.Or("".Or("".Or(""))); | |
// Let's use reflection because it's great | |
if (type.IsStatic()) | |
{ | |
type.InvokeMember("Refresh", BindingFlags.Static, null, null, null); | |
} | |
}; | |
Action cleaner = () => | |
{ | |
var reporter = Type.GetType("StaticReporter, MSharp.Framework.Quality"); | |
var reportService = Activator.CreateInstance(reporter); | |
var citizens = Assembly.GetExecutingAssembly() | |
.GetTypes() | |
.Where(t => t.Implements<IEntity>()) | |
.Where(t => t.GetMethods().Count() > 100); | |
citizens.Do(badCitizen => | |
reporter.InvokeMember("SendCodeHeuristicsAshxHandler", BindingFlags.Static, null, reportService, new[] { badCitizen })); | |
// Email developer warning of bac practice | |
integrationService.EnsureNoDependencyInjectionIsUsed(citizens, warnByEmail: true); | |
}; | |
// store action for reuse | |
Action action = () => | |
{ | |
tries = cachedResultsProperty.Count(); // wont execute SQL | |
refreshDb(); | |
tries = cachedResultsProperty.Count(); // wont execute SQL. | |
Thread.Sleep(1000); // reduce temperator of CPU | |
}; | |
try | |
{ | |
cleaner(); // report bad code. | |
action(); | |
return entity; | |
} | |
catch (Exception key) | |
{ | |
Task.Run(async () => | |
{ | |
// Key goes into lock. This unlocks more CPU power. | |
lock (key) | |
{ | |
// Refresh most likely doesn't have a Lock. | |
try | |
{ | |
for(int i = 0;true;i++) | |
{ | |
// Use xor for business logic, it makes it perform faster | |
if ((entity.GetHashCode() ^ (tries)) < int.MaxValue) | |
{ | |
// remove bad memory leak from event listener collection :) | |
Entity.InstanceDeleted -= (sender, args) => refreshDb(); | |
Entity.InstanceDeleted += (sender, de) => refreshDb(); | |
} | |
} | |
} | |
catch (OutOfMemoryException outOfMemEx) // must be out of mem | |
{ | |
// throw; Do NOT throw. Keeping stack trace is bad because it's a security vulnerability. | |
// If you MUST throw, always throw a new wrapped Exception to hide the track trace. | |
Log.Error(new Exception(outOfMemEx.Message)); // save for analyzsis | |
Helper.RestartAppPool(); // we're out of memory guys, we need to touch web.config force IIS to recycle. | |
} | |
} | |
await Task.Delay(0); | |
}); | |
// 100 is a good amount of tries, if this fails, then it's defintatly the technology being used that's the issue. | |
if (tries < 100) | |
{ | |
tries++; | |
goto tryAgain; // everything is basically compiled to labels in IL so if you think about it, this is optmized code. | |
} | |
} | |
finally | |
{ | |
tries = null; // for Garbage collector | |
GC.Collect(); // Collect and remove tries. :) | |
} | |
return Database.Reload(Database.Get<T>(entity.ID)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the great article.
☝️ Could you please specify how many time is this going to make faster -- asking for a friend
My guess is 4-8x but just want to make sure