Perl Can't call method "parse_html_string" or unbless reference - html

I'm trying to use the module HTML::Grabber to parse html in perl. It works when I just use it in my main process, but it throws me error when I attempt to use it with threading.
Specifically, I got this error,
Thread 1 terminated abnormally: Can't call method "parse_html_string"
on unblessed reference at /usr/local/ActivePerl-5.10/site/lib/HTML/Grabber.pm line 79.
where the creation of Grabber object.
$mech->get($link);
$dom = HTML::Grabber->new(html => $mech->content); #at this point
Any idea how to fix this weird problem?

The parse_html_string method is called on an XML::LibXML parser object.
XML::LibXML seems to have mixed support for threads:
http://search.cpan.org/~shlomif/XML-LibXML-1.78/LibXML.pod#THREAD_SUPPORT
What is probably happening is HTML::Grabber is creating the parser object when it is imported by your script in the main thread. Then you create a child thread, and since XML::LibXML does not clone between threads, the object disappears. You will need to do a runtime load of HTML::Grabber with require in the thread after it is spawned.
If that is not the case, you will have to boil down your problem to a small example and post the code here.

Related

SolidJS: "computations created outside a `createRoot` or `render` will never be disposed" messages in the console log

When working on a SolidJS project you might start seeing the following warning message in your JS console:
computations created outside a `createRoot` or `render` will never be disposed
There are some information available on this in SolidJS' Github repository issues. But after reading them I was still not quite sure what this was all about and whether my code was really doing something wrong.
I managed to track down where it came from and find a fix for it based on the documentation. So I'm providing the explanation and the solution for those Googling this warning message.
In essence this is a warning about a possibility of a memory leak due to a reactive computation being created without the proper context which would dispose of it when no longer needed.
A proper context is created a couple of different ways. Here are the ones I know about:
By using the render function.
By using the createRoot function. Under the hood render uses this.
By using the createContext function.
The first is by far the most common way, because each app has at least one render function call to get the whole show started.
So what makes the code go "out of context"?
Probably the most common way is via async calls. The context creation with its dependency tree happens only when the synchronous portion of the code finishes running. This includes all the export default function in your modules and the main app function.
But code that runs at a later time because of a setTimeout or by being in an async function will be outside of this context and any reactive computations created will not be tracked and might stick around without being garbage collected.
An example
Let's say you have a data input screen and have a Save button on it that makes an API call to your server to save the data. And you want to provide a feedback to the user whether the operation succeeded or not, with a nice HTML formatted message.
[msg,setMsg] = createSignal(<></>)
async function saveForm(){
...
setMsg(<p>Saving your data.<i>Please stand by...</i></p>)
const result=await callApi('updateUser',formData)
if(result.ok){
setMsg(<p>Your changes were <b>successfully</b> saved!</p> )
} else {
setMsg(<p>There was a problem saving your data! <br>Error: </p><pre>{result.error}</pre> )
}
}
...
<div>
...
<button onClick={saveForm} >Save</button>
{msg()}
</div>
This will produce the above mentioned warning when the API call returns an error, but not the other times. Why?
The reason for this is that SolidJS considers the code inserts inside JSX to be reactive, ie: need to be watched and re-evaluated. So inserting the error message from the API call creates a reactive computation.
The solution
I found the solution at the very end of the SolidJS doc. It's a special JSX modifier: /*#once*/
It can be used at the beginning of a curly brace expression and it tells the SolidJS compiler to explicitly not to make this a reactive expression. In other words: it will evaluated once and only once when the DOM nodes are created from the JSX.
In the above example here's how to use it:
setMsg(<p>There was a problem saving your data! <br>Error: </p><pre>{/*#once*/ result.error}</pre> )
After this there will be no more warning messages :)
In my case, I had an input and when that input changed I re-created an SVG drawing. Because the SVG creation was an expensive operation, I added a debounce in the createEffect function which ran when the input changed. debounce is a technique to defer the processing until the input stops changing for at least X amount of time. It involved running the SVG generation code inside the setTimeout function, thus being outside of the main context. Using the /*#once*/ modifier everywhere where I inserted an expression in the generated JSX has fixed the problem.

Correct way to pass runtime configuration to elixir processes

I'm trying to deploy an app to production and getting a little confused by environment and application variables and what is happening at compile time vs runtime.
In my app, I have a genserver process that requires a token to operate. So I use config/releases.exs to set the token variable at runtime:
# config/releases.exs
import Config
config :my_app, :my_token, System.fetch_env!("MY_TOKEN")
Then I have a bit of code that looks a bit like this:
defmodule MyApp.SomeService do
use SomeBehaviour, token: Application.get_env(:my_app, :my_token),
other_config: :stuff
...
end
In production the genserver process (which does some http stuff) gives me 403 errors suggesting the token isn't there. So can I clarify, is the use keyword getting evaluated at compile time (in which case the application environment doest exist yet)?
If so, what is the correct way of getting runtime environment variables in to a service like this. Is it more correct to define the config in application.ex when starting the process? eg
children = [
{MyApp.SomeService, [
token: Application.get_env(:my_app, :my_token),
other_config: :stuff
]}
...
]
Supervisor.start_link(children, opts)
I may have answered my own questions here, but would be helpful to get someone who knows what they're doing confirm and point me in the right way. Thanks
elixir has two stages: compilation and runtime, both written in Elixir itself. To clearly understand what happens when one should figure out, that everything is macro and Elixir, during compilation stage, expands these macros until everything is expanded. That AST comes to runtime.
In your example, use SomeBehaviour, foo: :bar is implicitly calling SomeBehaviour.__using__/1 macro. To expand the AST, it requires the argument (keyword list) to be expanded as well. Hence, Application.get_env(:my_app, :my_token) call happens in compile time.
There are many possibilities to move it to runtime. If you are the owner of SomeBehaviour, make it accept the pair {:my_app, :my_token} and call Application.get_env/2 somewhere from inside it.
Or, as you suggested, pass it as a parameter to children; this code belongs to function body, meaning it won’t be attempted to expand during compilation stage, but would rather be passed as AST to the resulting BEAM to be executed in runtime.

Dealing with invalid filehandles (and maybe other invalid objects too)

As indicated by Tom Browder in this issue, the $*ARGFILES dynamic variable might contain invalid filehandles if any of the files mentioned in the command line is not present.
for $*ARGFILES.handles -> $fh {
say $fh;
}
will fail with and X::AdHoc exception (this should probably be improved too):
Failed to open file /home/jmerelo/Code/perl6/my-perl6-examples/args/no-file: No such file or directory
The problem will occur as soon as the invalid filehandle is used for anything. Would there be a way of checking if the filehandle is valid before incurring in an exception?
You can check if something is a Failure by checking for truthiness or definedness without the Failure throwing:
for $*ARGFILES.handles -> $fh {
say $fh if $fh; # check truthiness
.say with $fh; # check definedness + topicalization
}
If you still want to throw the Exception that the Failure encompasses, then you can just .throw it.
TL;DR I thought Liz had it nailed but it seems like there's a bug or perhaps Ugh.
A bug?
It looks like whenever the IO::CatHandle class's .handles method reaches a handle that ought by rights produce a Failure (delaying any exception throw) it instead immediately throws an exception (perhaps the very one that would work if it were just delayed or perhaps something broken).
This seems either wrong or very wrong.
Ugh
See the exchange between Zoffix and Brad Gilbert and Zoffix's answer to the question How should I handle Perl 6 $*ARGFILES that can't be read by lines()?
Also:
https://github.com/rakudo/rakudo/issues/1313
https://github.com/rakudo/rakudo/search?q=argfiles&type=Issues
https://github.com/rakudo/rakudo/search?q=cathandle&type=Issues
A potential workaround is currently another bug?
In discussing "Implement handler for failed open on IO::CatHandle" Zoffix++ closed it with this code as a solution:
.say for ($*ARGFILES but role {
method next-handle {
loop {try return self.IO::CatHandle::next-handle}
}
})
I see that tbrowder has reopened this issue as part of the related issue this SO is about saying:
If this works, it would at least be a usable example for the $*ARGFILES var in the docs.
But when I run it in 6.d (and see similar results for a 6.c), with or without valid input, I get:
say not yet implemented
(similar if I .put or whatever).
This is nuts and suggests something gutsy is getting messed up.
I've searched rt and gh/rakudo issues for "not yet implemented" and see no relevant matches.
Another workaround?
Zoffix clearly intended their code as a permanent solution, not merely a workaround. But it unfortunately doesn't seem to work at all for now.
The best I've come up with so far:
try {$*ARGFILES} andthen say $_ # $_ is a defined ArgFiles instance
orelse say $!; # $! is an error encountered inside the `try`
Perhaps this works as a black-and-white it either all works or none of it does solution. (Though I'm not convinced it's even that.)
What the doc has to say about $*ARGFILES
$*ARGFILES says it is an instance of
IO::ArgFiles which is doc'd as a class which
exists for backwards compatibility reasons and provides no methods.
And
All the functionality is inherited from
IO::CatHandle which is subtitled as
Use multiple IO handles as if they were one
and doc'd as a class that is
IO::Handle which is subtitled as
Opened file or stream
and doc'd as a class that doesn't inherit from any other class (so defaults to inheriting from Any) or do any role.
So, $*ARGFILES is (exactly functionally the same as) a IO::CatHandle object which is (a superset of the functionality of) an IO::Handle object, specifically:
The IO::CatHandle class provides a means to create an IO::Handle that seamlessly gathers input from multiple IO::Handle and IO::Pipe sources. All of IO::Handle's methods are implemented, and while attempt to use write methods will (currently) throw an exception, an IO::CatHandle is usable anywhere a read-only IO::Handle can be used.
Exploring the code for IO::CatHandle
(To be filled in later?)

Trying to clean merged JS/CSS cache, but model "core/design_package" is a non-object

I have made a new PHP file at the root directory of Magento (next to index.php) and it contains this code:
require 'app/bootstrap.php';
require 'app/Mage.php';
Mage::getModel('core/design_package')->cleanMergedJsCss();
Produces this error:
Fatal error: Call to a member function getModelInstance() on a non-object
in /home/edpadev/public_html/stage/bsr/app/Mage.php on line 463
From my understanding, Magento should dig up that particular method in /app/code/core/Mage/Core/Model/Design/Package.php.
I cannot var_dump it since it cannot instantiate it, I just get the same error when trying to do that.
I am able to call our third-party cache module's observer model and use its methods, and use the simple Mage::app()->cleanCache();, but the core function above does not work, though that is how it appears in examples by other developers in Google search results.
Try this. You might need to setup the store
umask(0);
require 'app/Mage.php';
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

Grails JSON Marshalling Works after first running compile

I'm experiencing a discrepancy between the first compilation of a Grails app and the compilation that happens when a file changes while the app is running.
Background:
My app creates some spring beans from Spring LDAP (docs) using conf/spring/resources.groovy.
I have an LdapUser.groovy class in src/groovy (I'm using it similarly to a domain class, except it isn't in grails-app/domain as it doesn't map to a database table).
In BootStrap.groovy I register a JSON marshaller for LdapUser (using JSON.registerObjectMarshaller).
I have a controller with an index method that responds a list of LdapUser objects. This renders correctly in JSON (according to the marshaller).
With that background, here are the pieces of the problem:
When the show method, which responds a single LdapUser, gets called, I get an exception that LdapUser cannot be converted to grails.converters.JSON. (fair enough)
But, if I save the LdapUser.groovy file, thus invoking a recompile on the file while the app is running, the JSON marshaller suddenly works fine.
Before saving the LdapUser.groovy, my controller has a to an LdapUserRepo (a class instantiated via an #EnableLdapRepositories annotation on the controller), but this reference becomes null after I save LdapUser.groovy. I'm not sure how this relates to the problem, as I was also able to reproduce the problem in a controller lacking an injected LdapUserRepo (but with the annotated controllers still in the app).
I also at one point was setting an asType method on the LdapUser class, which was called as expected before the save-invoked recompile. After the recompile, however, my asType method was no longer called and the JSON marshaller was taking over. ( I was doing exception-worthy things in the asType that were throwing before recompile and not throwing after... )
My understanding of the problem is therefore:
Somehow the asType method of the LdapUser.groovy class is not being automatically generated on first compile when running the app, but is being generated on subsequent compiles.
The LdapUser class is tied to the LdapUserRepo in more ways than merely being a type the Repo uses, and the recompile is not reflecting that connection correctly.
Methods rendering lists of objects are somehow unaffected by the asType method. This leads me to believe that the JSON marshaller gets called directly on list elements (instead of via asType) when the list asType has been called (whether or not the "as" operation is implicit...).
My question then is:
what is the Grails compiler doing differently on run-app vs on compile while app is running that could be causing this behavior?
how can I restructure things to ensure it works properly out of the box?
If I need to RTFM, what would be the FM section? (My google-fu is sadly quite weak).
Note: this question is vaguely similar, but doesn't have any meaningfulness to the answer:
Grails: Defining a JSON custom marshaller as static method in domain