How to declare a variable that persists subroutines - varnish-vcl

During the recv subroutine I am currently changing my backend to another backend to handle the request, I need to declare a variable that will hold the value for the first/original backend that it was set to, so that when the request is restarted, I can then assign the backend back to this.
I can't just use the name for the backend and simply assign it back as I need it to be dynamic, storing it in a variable seems like the simplest solution but I can't seem to find any information on how this can be achieved through subroutines/ restarts.
If not possible are there any other solutions I could try to achieve this? Probably not possible from what I understand but even the ability to access an array of the backends defined and picking the first one would suffice, I just cant rely on naming the backend to assign it back.

Unfortunately it isn't possible to declare a variable as a BACKEND type (which is what req.backend returns).
See this 'Fastly Fiddle' example that demonstrates you'll get a compiler error of:
Expected variable type, one of: BOOL, INTEGER, FLOAT, TIME, RTIME, IP or STRING
There also isn't any way to get a list of available backends via VCL either.
Additionally you would need to hardcode the backend value (i.e. you need to explicitly know what backends are defined from the VCL perspective) as trying to store a backend into a header or variable will convert it to a STRING type representation (such as 6kLtu7NicmMs0DtKsuite9--F_origin_0).
This means even if you were able to parse the actual F_origin_0 backend from the string you wouldn't be able to assign it as a value to req.backend as that expects the value to be of type BACKEND (and VCL doesn't provide a way, AFAIK, to convert a string into that type).

Related

QMimeData encoding types

In my app I'm doing internal drag and drops with a QTreeView. Using the tutorial I can happily drag and drop a single leaf by encoding it into a string list using the mime type "application/vnd.text.list".
I then wanted to drag and drop a tree node that had some children and thought the best route to doing this would be to encode the pointer to the node and iterate through all the children in the dropMimeData method.
I declared a mime type in the mimeTypes() method:
QStringList toResultModel::mimeTypes() const {
QStringList types;
types << "text/plain";
types << "application/vnd.mypointerlist.list";
return types;
}
And tried to pass the same string list across, but the application crashes in the dropMimeData() method.
It seems the mime type "application/vnd.text.list" has some hidden meaning which I am unable to find.
I have found this source code: http://fossies.org/linux/tora/src/toresultmodel.cpp where the author sets up a custom coding type "application/vnd.tomodel.list" and also uses "application/vnd.int.list".
What are the rules in using encoding types?
Where are the built-in types strings defined?
Which type should I use for passing a pointer to a tree node?
Four years later...
From the information you give, if your method crashes, it's not related to Drag and Drop in particular, there is some error you need to find in the code. that said, let me clarify D&D in Qt, and answer your question about MIME types. While you have indeed solved the problem you had four years ago, this may be useful for other users today.
You may define your own type for the purpose of your application or reuse an existing one. How to choose?
Can you use an existing MIME type, like text/plain?
Think about your application being the target of a D&D operation initiated from another application. Can you accept an existing MIME type and retrieve your data from it?
Think about another application being the target of a D&D operation initiated from within your application. Could this application handle an existing MIME type?
If this answer is no to any of the questions, then you might have to use your own specific MIME type.
The format name itself is not important
The constraint is that it must be unique, so that you can't receive incorrectly formatted MIME data from another application, and other applications can identify the MIME type as one they cannot handle, and ignore it.
The exact MIME type name doesn't matter as you'll provide the encoder and the decoder into your data model (e.g. see this introduction to view/model for Qt), as well as other information about the MIME type(s) used.
In QAbstractItemModel::mimeTypes, list only the MIME types you are able to deal with. If you don't plan to accept or send MIME data from/to other applications, there is no need to allow more than your specific MIME type.
When your application is the source of a D&D operation, encode (serialize) the MIME data in QAbstractItemModel::mimeData(indexes). The result of the serialization must be a byte array, even when there are multiple indexes to be dragged. The internal format is yours. Include any information required to decode (de-serialize) MIME data. Note that you must provide encoded data in each of the MIME type you've listed in QAbstractItemModel::mimeTypes (see previous point).
When your D&D data are dragged over your application UI, QAbstractItemModel::canDropMimeData(self, mime_data, action, row, column, parent) is called to determine if this location is valid for a drop. You may determine here whether the drop should be allowed at this location. In particular, you may test the content of the MIME data provided, and use mime_data.hasFormat(mime_type) to check if the format you expect is found in the data about to be drooped. Returning false will prevent a drop at this location and a "not allowed here" indication will be provided to the user (this won't cancel the D&D operation itself, the user can continue to move the mouse elsewhere).
When the data is actually dropped, QAbstractItemModel::dropMimeData(mime_data, action, row, column, parent) is called. Get the MIME data format(s) used using QMimeData::hasFormat(mime_type). If you don't find the MIME type you expect, ignore the drop operation as you cannot decode the data provided (the D&D was initiated from another application). This shouldn't happen as prior to drop data, the application has called QAbstractItemModel::canDropMimeData as seen in the previous point. If everything is ok decode the MIME data, and update your model with the data received.
On the other hand, your tree leaf data may fit as path+name encoded in text/plain MIME data, so maybe you can just use this type too. However as other applications can generate text/plain data that don't contain a tree leaf description, you need, in this case, to have a mean to identify irrelevant data and ignore them. It's obvious such approach will need more code for verification of the validity of the drop action than when using a specific MIME type. However this allows to interact with other applications, and is indeed relevant to drag from well know applications like Excel (e.g. cell content) or Firefox (e.g. rich text or image), else we couldn't re-use information from these applications using D&D.
Do you need to use vnd prefix?
vnd in the MIME type means "vendor specific". This prefix is used to distinguish vendors created MIME types from those created by IANA authority. From RFC 6838:
Vendor-tree registrations will be distinguished by the leading facet
"vnd.". That may be followed, at the discretion of the registrant, by
either a media subtype name from a well-known producer (e.g.,
"vnd.mudpie") or by an IANA-approved designation of the producer's
name that is followed by a media type or product designation (e.g.,
vnd.bigcompany.funnypictures).
So in your Drag&Drop tutorial the application/vnd.text.list is a specific one supposedly created by some vendor for their own purpose. Same for application/vnd.mypointerlist.list
In contrast, text/plain is a standard MIME type defined by IANA in RFC 2046. This defines a human readable text:
Plain text does not provide for or allow formatting commands, font
attribute specifications, processing instructions, interpretation
directives, or content markup. Plain text is seen simply as a
linear sequence of characters, possibly interrupted by line breaks
or page breaks. Plain text may allow the stacking of several
characters in the same position in the text. Plain text in scripts
like Arabic and Hebrew may also include facilitites that allow the
arbitrary mixing of text segments with opposite writing directions.
For your type, you may want to use vnd followed by a subtype which is specific to your application, for consistency considerations. But as seen, the actual name is not important, as long as you know which one you use and you are not interacting with other applications in the D&D chain.

BizTalk Business Rule Engine Compare DateTimeNow within a range of dates?

I try to use Between predicate to compare the current datetime with a range of date time.
I reference mscorlib assembly and use get_Now() within DateTime class in the assembly to get DateTimeNow. I have problem to compare this current datetime with the range.
my condition is like:
DateTimeNow is between 2012-08-03 07:00:00 and 2012-08-04 07:00:00
DateTimeNow at my region should be 2012-08-03 16:33:20 for this moment. It should between the range I specified. But it seems does not work. If I replace DateTimeNow with 2012-08-03 16:33:20, it works.
It seems for some reason my DateTimeNow does not work. Anyone has any idea?
I found to use Get_Date() function in .net mscorlib assembly, you have to modify your machine registry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\BusinessRules\3.0\StaticSupport (DWORD), give value 1
Details in:
http://blogs.msdn.com/b/richardbpi/archive/2005/11/14/492489.aspx
http://kinnaribhute.blogspot.co.nz/2008/04/some-interesting-stuff-about-biztalk.html
I am not sure how this will affect the production server, if the production server environment is not clustered with multiple node, there will be an outage for reboot the server.
There is an impedance mismatch between the way facts are logically modelled in the engine and the way objects are modelled in .NET code, and one effect of this is the problem of calling static methods. If you set the StaticSupport flag as described by Xiao Han, the engine changes its behaviour, treating static methods much as if they were built-in functions or predicates. By default, however, the engine treats static methods as behaviour of facts. Physically, a fact is an object in the working memory of the engine, and each fact has to be asserted to the engine before it's methods can be used. So, to call the static Now property getter on DateTime, you first have to assert a DateTime object to the engine. Of course, DateTime is a value type (structure), but that's OK because, when you execute a rule set, you assert a single fact as an Object or a collection of facts as an Object array. .NET will automatically box a DateTime (internally wrap it as an object) passed in this way.
It seems mad, I realise, having to assert an object to the engine in order to call a static method (or, in this case, a property getter, which is really a method, of course) on the type of that object. It would probably have been better if the engine had been built to treat static methods as built-ins by default. However, that was not the case. In addition, it would have been much better if Microsoft had implemented the StaticSupport flag at the level of individual rule sets, or even individual rules. Implementing it in the registry (machine-level), or alternatively configuring it in the .config file (application-level; use ) in this way can pose real problems because it can break rule sets that were written to use the opposite value of the flag.
Another point to bear in mind in that the Static Support can also be set to '2'. In this case, if you call a static method with no parameters, or if you call it with constant values only, and if you call it as a predicate in a condition or as an argument to another function, then the engine will evaluate the static member just once and cache the result.

Can I declare a global variable in xquery in Marklogic Server?

I want a global variable which I can use in my different .xqy pages. Can I declare such a variable in xquery in Marklogic Server ?
You can declare a variable in any module. For instance, it is config.xqy.
declare variable $PRECISION as xs:integer := 4;
For using this variable you need to import this module in your work module.
import module namespace config = "http://your-namespace" at "config.xqy";
And refer to this variable:
$config:PRECISION
If your application is running on a single E-node, you can use server fields , which are sort of designed for this use case as well.
If you need values accessible across the server, there is a library in the Marklogic XQuery Commons for storing persistent key/value pairs:
https://github.com/marklogic/commons/blob/master/properties/properties.xqy
And you may have already considered this, but you could also just simply store the global data in a document on the database and access with doc() - or eval() if you need to get to it from a different database.
You have a few options. If you need a global constant variable, the config.xqy method mentions in #Andrew Orlov's answer is great because you avoid any locking from concurrent access to a properties.xml file.
If you need a variable that can be mutated across a cluster of nodes, the property.xqy example linked by #wst appears to use globally assigned namespaces to embed a retrievable key and value. Pretty clever. However, I'm not sure how much this is meant for heavy levels of change.
The E-node specific variable from #Eric Bloch is good, but please also be aware that it will not survive a system restart.
I'd be interested to know how these all compare performance-wise.

Optional Invalid Query String Variables

This is a somewhat philosophical issue. I have a .net (but could be any platform) based helper library that parses query string values. Take for example a variable that returns an Int32: my framework has an option that specifies whether this value is required or optional. If it is required but not provided, the framework throws an exception. If it is optional and not specified, it returns a null.
Now an edge case has come up based on users hacking (in a good way) our urls. If they specify a variable with either an invalidly formatted Int32 ("&ID=abc") or provide the variable but not specify a value ("&id="), should the framework throw an exception or should it return a null?
Part of me feels that invalid variables or formats should return a null. It might be valid to argue that even if the parameter is optional, an invalidly formatted query string or value should still throw an exception.
Thoughts?
Since this is philophical ...
On something like an ID, I would agree with Shawn that it is a 404, especially if you are thinking in terms of state. There is no object, so not found. But, ID may not tie directly to a resource in all cases.
If the item is truly optional, a null is okay. But optional should mean "if present it makes the call more specific" in this case and there should always be a fallback. I don't see this in ID, unless the ID is keyed to an optional part of the page.
In the long run, I think you should look at the business reason for the page and what each variable means.
I believe that if a variable is optionaly, providing the variable but not specifying the value is equivalent to ommitting the variable itself. In this case, returning null seems OK.
However, providing an invalidly formatted value ought to cause an Exception, since the intent was to provide a value. In this case the user ought to be notified through some sort of validation mechanism.
A HttpException of 404 (Not Found). Your web application framework should know how to catch these errors and redirect to the proper page.
This is actually a not found error because the resources that the ID is pointing to does not exist.
I suspect there's no "right" answer to your question. If I were a developer using your library, I would expect/hope that the public API would include in its code comments, a description of how the function behaves when the URL param includes bad (wrong type) data.
You might also be able to craft your public API to get the best of both worlds: .NET seems to have adopted the "Parse" / "TryParse" approach in many places. If I'm the caller and I want the function to throw if given invalid data, I call Parse(). If I don't want it to throw, I call TryParse(). In my opinion, that is a nice pattern to follow with your API as well.

How can I preserve the QueryString semantics when converting an MFC CHttpServer based web server to ASP.Net?

In a legacy MFC CHttpServer based web server, we have a command parsing map something like this:
BEGIN_PARSE_MAP(MyHttpServer, CHttpServer)
ON_PARSE_COMMAND(MyPage, MyHttpServer, ITS_I4 ITS_I4 ITS_I4 ITS_I4 ITS_PSTR ITS_PSTR ITS_PSTR ITS_I4)
ON_PARSE_COMMAND_PARAMS("intParam1=11 intParam2=12 intParam3=13 intParam4=14 strParam5=s5 strParam6=s6 strParam7=s7 intParam8=18")
END_PARSE_MAP(MyHttpServer)
This defines a page accessible at http://host/path/dllname.dll?MyPage that accepts up to 8 parameters named intParam1, intParam2, intParam3, intParam4, strParam5, strParam6, strParam7, and intParam8.
The calling applications can invoke the page with the parameters in a named fashion like this:
http://host/path/dllname.dll?MyPage?intParam4=32&strParam7=somestring
But the way MFC command parsing maps work, they can also call it with unnamed parameters as long as they are provided in the order defined by the map:
http://host/path/dllname.dll?MyPage?21&22&23&24&string5&string6&string7&28
I would like to replace this old code with an ASP.Net page, but we have existing calling applications that will not be changed that invoke the page using both styles of parameter passing, named and unnamed.
I can easily manage the necessary URL rewriting to allow an ASP.Net page to respond to the URL as given above, replacing the path/dllname.dll? MyPage portion with the path to an .aspx page or .ashx handler.
The problem comes in when trying to handle the unnamed parameters in an equivalent fashion to the old MFC parameter parser. Request.QueryString treats all the unnamed parameters as being named with null and Request.QueryString[null] returns a comma-separated list of the values. This is pretty close to workable, but should one of the parameters actually contain a comma, this encoding falls apart because the extra comma is not escaped and splitting the string on the commas will end up with too many parameters.
In classic ASP, I believe Request.QueryString(...) returned a collection of all the parameters that were identically named. There seems to be no equivalent to that in ASP.Net that I can find.
As a secondary issue, the MFC command parsing map had some pretty convoluted logic for dealing with a mixture of named and unnamed parameters. Although the callers of the page in question will not be mixing their usage in this way, I am interested in perhaps duplicating the logic for completeness sake. Can anyone confirm that MFC's behavior was essentially the following?
Process all parameters in the URL from left to right, using & as separator.
If named (has an equal sign), apply the value to the parameter with the corresponding name, regardless of its position. If that parameter already assigned a value, error.
If unnamed, apply the value to the parameter at the nth position in the command parsing map, where n is the number of already processed unnamed parameters plus 1. If that parameter was already assigned a value, error.
Apply default values from command parsing map to any parameters not assigned above
If any parameters from command parsing map have not been assigned a value, error.
One more interesting note, it appears that Request.QueryString.ToString() will nearly reconstitute the original parameters on the URL, but it always moves the parameters with identical names to be together, including the unnamed parameters I am concerned with here.
Not sure if solves your problem, but you could try using Request.PathInfo. This will give you everything entered after the page, which you could then parse manually using something like a regex.
For example, if you had the URL:
http://host/path/dllname.dll?MyPage?21&22&23&24&string5&string6&string7&28
The Request.PathInfo property would return:
?MyPage?21&22&23&24&string5&string6&string7&28
Processing this into a set of values that you can work with could also be problematic as you've got both named and un-named parameters, but this should be achievable using regular expressions and/or splitting the string.
I found that Request.QueryString has a GetValues() method. This returns an array of strings and solves the problem of a comma being embedded within one of the values. It'll be even easier to use than having to split the results of Request.QueryString[null].
I still have a bit of work to use this to implement an MFC-like mapping of URL parameters that handles both named and unnamed parameters.

Resources