Where did LoaderService go? - anglesharp

Upgrading AngleSharp from 0.9.6 to 0.9.9 I have this line of code no longer compiling:
return configuration.With(LoaderService(new[] { requester }));
It complains that LoaderService does not exist in the current context. So what happened to LoaderService? Is there a replacement? Does it still exist but just somewhere else?

Good question. Sorry for being late to the party, but even though you may have solved your problem someone else is having a hard time figuring it out.
LoaderService was essentially just a helper to create a loader. But having a service for anything creating a little thing would be overkill and not scale much. Also AngleSharp.Core would need to define all these. So, instead a generic mechanism was introduced, which allows registering such "creator services" via Func<IBrowsingContext, TService>.
However, to solve your piece of code I guess the following line would do the trick:
return configuration.WithDefaultLoader(requesters: requester);
This registers the default loader creator services (one for documents, one for resources inside documents) with the default options (options involve some middleware etc.).
Under the hood (besides some other things) the following is happening:
// just one example, config.Filter is created based on the passed in options
return configuration.With<IDocumentLoader>(ctx => new DocumentLoader(ctx, config.Filter));

Related

redux-injectors: Using yield select in saga before reducer and saga are injected

Hello this is my first question. I am trying to set up a project where modules along with the redux and sagas will be injected into the main app, using redux-injectors. In my sagas I want to use yield select, to check if an action has updated the state and then carry on. For example, when I post an image, I want to make sure there were no errors in posting the file and then move on. I use the following function:
export const imageErrors = (state: RootState): IImagesErrorState => state.image.errors
and then in the saga.ts file I use it as such:
if (imagesErrors?.postImageError !== null) {
throw imagesErrors.postImageError
}
this works fine as long as the state.image exists in the root state from the beginning. However, how do I do that when I want to inject this state later on using useInjectReducer and useInjectSaga? I obviously get an error
Property 'image' does not exist on type 'Reducer<CombinedState<{ user: CombinedState<{ auth: IAuthState; errors: IErrorState; }>; }>, AnyAction>'.ts(2339)
So how do we handle selectors of specific pieces of state, since state does not yet include them?
Thank you so much.
Can't talk about the Typescript part of things, but in terms of architecture you've got two options.
One is the obvious - that is to add conditions or ? everywhere to avoid errors from accessing missing properties, but that can get tedious quickly.
The other probably better option is to rethink your state & application chunks. What is this saga that is accessing state that isn't existing yet? Does it need to run before you have such state? If not, let's move the saga to the same chunk as the reducer. In the opposite case, where you need the saga to be running e.g. as part of the runtime chunk, then perhaps the image state should be in the runtime chunk as well.

Axon Framework Event Package Refactoring

I have a set of events that have been refactored to another package. This works as is until I execute the event replay. Digging deeper I noticed a payloadtype in the domainevententry table and figure changing this would be sufficient but alas it seems the xml root element of the event needs to be changed as well. I am hoping there is a simple way to do this.
I cannot find any examples on upcasting to different packages or using XStream aliasing so any help would be greatly appreciated.
Thanks
As you noticed, the default payload type stored in events is the fully qualified class name. This ensures that out of the box serialization and deserialization work as intended. However, moving classes around thus means the payload type can no longer be found, requiring some adjustment to be made.
You could have used the EventTypeUpcaster, as referred to in the Reference Guide. The EventTypeUpcaster is dedicated to adjusting the payload type, and thus can also be used to deal with changing package names.
When using (the default) XStreamSerializer, aliasing the tags would indeed also work. How to set aliases can be seen here for example. AS noticed in that sample, the alias is added to the XStream instance. The XStreamSerializer uses an XStream instance to support de-/serialization from/to XML. To adjust the XStream instance, you can simply use the builder paradigm on the XStreamSerializer. The JavaDoc of the builder should be specific enough to help you out how to use it.
Went the long way round with this but it seems to work. As always, backup your database before executing large volume changes. I also restarted the service using the database on completion. Needless to say I will make sure the events are in logical packages before deploying next time :)
Database Engine: Postgres 10
Table: domainevententry
update domainevententry
set
payloadtype = '<new.package.Classname>',
payload = lo_from_bytea(0, decode(REPLACE(
subquery.output,
'<old.package.Classname>',
'<new.package.Classname>'
), 'escape'))
from (
SELECT eventidentifier, payloadtype, encode(lo_get(payload::oid), 'escape') as output FROM domainevententry
WHERE eventidentifier in (
'<event guid 1>',
'<event guid 2>'
)
AND payloadtype = '<old.package.Classname>'
) as subquery
where domainevententry.eventidentifier = subquery.eventidentifier;
Once that is completed I needed to update the OWNER of the large object:
ALTER LARGE OBJECT <LargeObjectId> OWNER TO database_role;
Probably not the most elegant solution but based on the time constraints I have, it did the job. There are probably encoding issues with this solution for the large object but it all worked out for me in the end. Feel free to share any optimizations that would make the above more suitable.
Firing off the Axon Framework replays rebuilt the projections and everything lined up.

Register callback in Autofac and build container again in the callback

I have a dotnet core application.
My Startup.cs registers types/implementations in Autofac.
One of my registrations needs previous access to a service.
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterSettingsReaders(); // this makes available a ISettingsReader<string> that I can use to read my appsettings.json
containerBuilder.RegisterMyInfrastructureService(options =>
{
options.Username = "foo" //this should come from appsettings
});
containerBuilder.Populate(services);
var applicationContainer = containerBuilder.Build();
The dilemma is, by the time I have to .RegisterMyInfrastructureService I need to have available the ISettingsReader<string> that was registered just before (Autofac container hasn't been built yet).
I was reading about registering with callback to execute something after the autofac container has been built. So I could do something like this:
builder.RegisterBuildCallback(c =>
{
var stringReader = c.Resolve<ISettingsReader<string>>();
var usernameValue = stringReader.GetValue("Username");
//now I have my username "foo", but I want to continue registering things! Like the following:
containerBuilder.RegisterMyInfrastructureService(options =>
{
options.Username = usernameValue
});
//now what? again build?
});
but the problem is that after I want to use the service not to do something like starting a service or similar but to continue registering things that required the settings I am now able to provide.
Can I simply call again builder.Build() at the end of my callback so that the container is simply rebuilt without any issue? This seems a bit strange because the builder was already built (that's why the callback was executed).
What's the best way to deal with this dilemma with autofac?
UPDATE 1: I read that things like builder.Update() are now obsolete because containers should be immutable. Which confirms my suspicion that building a container, adding more registrations and building again is not a good practice.
In other words, I can understand that using a register build callback should not be used to register additional things. But then, the question remain: how to deal with these issues?
This discussion issue explains a lot including ways to work around having to update the container. I'll summarize here, but there is a lot of information in that issue that doesn't make sense to try and replicate all over.
Be familiar with all the ways you can register components and pass parameters. Don't forget about things like resolved parameters, modules that can dynamically put parameters in place, and so on.
Lambda registrations solve almost every one of these issues we've seen. If you need to register something that provides configuration and then, later, use that configuration as part of a different registration - lambdas will be huge.
Consider intermediate interfaces like creating an IUsernameProvider that is backed by ISettingsReader<string>. The IUsernameProvider could be the lambda (resolve some settings, read a particular one, etc.) and then the downstream components could take an IUsernameProvider directly.
These sorts of questions are hard to answer because there are a lot of ways to work around having to build/rebuild/re-rebuild the container if you take advantage of things like lambdas and parameters - there's no "best practice" because it always depends on your app and your needs.
Me, personally, I will usually start with the lambda approach.

How can I tell the Closure Compiler not to rename an inner function using SIMPLE_OPTIMIZATIONS?

How can I tell the Closure Compiler not to rename an inner function? E.g., given this code:
function aMeaninglessName() {
function someMeaningfulName() {
}
return someMeaningfulName;
}
...I'm fine with Closure renaming the outer function (I actively want it to, to save space), but I want the function name someMeaningfulName left alone (so that the name shown in call stacks for it is "someMeaningfulName", not "a" or whatever). This despite the fact that the code calling it will be doing so via the reference returned by the factory function, not by the name in the code. E.g., this is purely for debugging support.
Note that I want the function to have that actual name, not be anonymous and assigned to some property using that name, so for instance this is not a duplicate of this other question.
This somewhat obscure use case doesn't seem to be covered by either the externs or exports functionality. (I was kind of hoping there'd be some annotation I could throw at it.) But I'm no Closure Compiler guru, I'm hoping some of you are. Naturally, if there's just no way to do that, that's an acceptable answer.
(The use case is a library that creates functions in response to calls into it. I want to provide a version of the library that's been pre-compressed by Closure with SIMPLE_OPTIMIZATIONS, but if someone is using that copy of the library with their own uncompressed code and single-stepping into the function in a debugger [or other similar operations], I want them to see the meaningful name. I could get around it with eval, or manually edit the compressed result [in fact, the context is sufficiently unique I could throw a sed script at it], but that's awkward and frankly takes us into "not worth bothering" territory, hence looking for a simple, low-maintenance way.)
There is no simple way to do this. You would have to create a custom subclass of the CodingConvention class to indicate that your methods are "local" externs (support for this was added to handle the Prototype library). It is possible that InlineVariables, InlineFunctions, or RemoveUsedVariables will still try to remove the name and would also need to be fixed up.
Another approach is to use the source maps to remap the stack traces to the original source.
read the following section
https://developers.google.com/closure/compiler/docs/api-tutorial3#export
Two options basically, use object['functionName'] = obj.functionName or the better way
use exportSymbol and exportProperty both on the goog object, here is the docs link for that
http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.html
-- edit
ah, i see now, my first answer is not so great for you. The compiler has some interesting flags, the one which might interest you is DEBUG, which you can pass variables into the compiler which will allow you to drop some debugging annotations in via logging or just a string which does nothing since you are using simple mode.
so if you are using closure you can debug against a development version which is just a page built with dependiencies resolved. we also the drop the following in our code
if(DEBUG){
logger.info('pack.age.info.prototype.func');
}

How do you like to define your module-wide variables in drupal 6?

I'm in my module file. I want to define some complex variables for use throughout the module. For simple things, I'm doing this:
function mymodule_init() {
define('SOME_CONSTANT', 'foo bar');
}
But that won't work for more complex structures. Here are some ideas that I've thought of:
global:
function mymodule_init() {
$GLOBALS['mymodule_var'] = array('foo' => 'bar');
}
variable_set:
function mymodule_init() {
variable_set('mymodule_var', array('foo' => 'bar'));
}
property of a module class:
class MyModule {
static $var = array('foo' => 'bar');
}
Variable_set/_get seems like the most "drupal" way, but I'm drawn toward the class setup. Are there any drawbacks to that? Any other approaches out there?
I haven't seen any one storing static values that are array objects.
For simple values the drupal way is to put a define in the begining of a modules .module file. This file is loaded when the module is activated so that is enough. No point in putting it in the hook_init function.
variable_set stores the value in the database so don't run it over and over. Instead you could put it in your hook_install to define them once. variable_set is good to use if the value can be changed in an admin section but it's not the best choice to store a static variable since you will need a query to fetch it.
I think all of those methods would work. I have never used it in this fashion, but I believe the context module (http://drupal.org/project/context) also has its own API for storing variables in a static cache. You may want to check out the documentation for the module.
It's always a good practice to avoid globals. So that makes your choice a bit easier.
If you err towards a class, you'll be writing code that is not consistent with the D6 standards. There are a lot of modules that do it but I personally like to keep close to the Drupal core so I can understand it better. And code that's written in different styles through the same application can have an adverse effect on productivity and maintenance.
variable_set() and define() are quite different. Use the former when you can expect that information to change (a variable). Use the latter for constants. Your requirements should be clear as which one to use.
Don't worry too much about hitting the database for variable_set/get. If your software is written well, it should not effect performance hardly at all. Performance work arounds like that should only be implemented if your applications has serious performance issues and you've tried everything else.

Resources