purge sitecore analytics geoip records inside request pipeline - sitecore

Our analytics database has alot of empty data stored in cachedValue. This data seems to get returned forever. I want to basically check that the required data is present in the cache, and if not, then do a new lookup.
I also want to allow testers to trigger this fresh lookup using a query string variable.
I've used reflector and noticed some Invalidate functions, but this appears to just clear cookies or remove the data from the in memory cache. It looks like I want to set the cachedGeoIpHandle.GeoResolveState = Failed, not sure how to do this yet.
I also see exactly where I could make this happen in the GeoIpManager, but I can override, extend that class.
Thanks.

Related

REST API - Update of single resource changes multiple others

I'm looking for a way how to deal with a following problem:
Imagine you modify a resource and that subsequently causes update of other resources.
E.g. you issue a PUT to, say /api/orders/1234, which by definition changes state of all other Orders of given user. There may be UI clients that display the table of Orders and they should know that not only single item in the table was updated, but eventually other as well.
Now, is there any standard way how inform a clients about such a situation?
So far I can only think of sending back the 205 Reset Content HTTP status code to inform the client that he should refresh the state, as not just a single thing was changed.
There are multiple solutions.
You can define specific resources as non-cacheable, so the client does not cache them at all. (no-store)
You can try giving a max-age of 0, so the client will have to re-validate those resources always. In this case you might have to implement ETags and conditional GETs, but it will be easier on the server than option 1.
Some push method like WebSockets.
If you really want to "notify" potentially multiple clients of a change, then it sounds like you would need option 3.
However, correctly configured caching is normally good enough. For example you could mark not-yet-executed orders as not cached (max-age=0), but as soon as it is executed, you might mark it to be cached indefinitely, since it can not change anymore.

Sharing data across Sitecore pipelines

I´m trying to perform some actions in the pipeline "httpRequestBegin" only when necessary.
My processor is executed after Sitecore resolves the user (processor type="Sitecore.Pipelines.HttpRequest.UserResolver, Sitecore.Kernel" ), as i´m resolving the user too if Sitecore is not able to resolve it first.
Later, i want to add some rendering in the pipeline "insertRenderings", only if actions in the previous pipeline were executed (If i resolved the user, show a message), so i´m trying to save some "flag" in the first step, to check in the second.
My question is, where can I store that flag? I´m trying to find some kind of "per request" cache...
So far, I've tried:
The session: Wrong, it's too early, session doesn't exists yet.
Items (HttpContext.Current.Items): It doesn't work either, my item is not there on the seconds step.
So far i'm using the application cache (HttpContext.Current.Cache) with some unique key, but I don´t like this solution.
Anybody body knows a better approach to share this "flag"?
You could add a flag to the request header and then check it's existence in the latter pipelines, e.g.
// in HttpRequest pipeline
HttpContext.Current.Request.Headers.Add("CustomUserResolve", "true");
// in InsertRenderings pipeline
var customUserResolve = HttpContext.Current.Request.Headers["CustomUserResolve"];
if (Sitecore.MainUtil.GetBool(customUserResolve, false))
{
// custom logic goes here
}
This feels a little dirty, I think adding to Request.QueryString or Request.Params would been nicer but those are readonly. However, if you only need this for a one time deal (i.e. only the first time it is resolved) then it will work since in the next request the Headers are back to default without your custom header added.
HttpContext.Current.Cache or HttpRuntime.Cache could be the fastest solution here. Though this approach would not preserve data when the AppPool gets recycled.
If you add only a few keys to the cache and then maintain them, this solution might work for you. If each request puts an entry into the cache, it may eventually overflow the memory used by worker process in a long run.
As alternative to this you may try to use Sitecore.Context.ClientData property. It uses ClientDataStore that employs a database (look for clientDataStore section in the web.config file) to store data. These entries can survive the AppPool recycle.
Though if you use them a lot, it may become a bottleneck under the load when you need to write to and/or read from the entries.
If you do know that there could be a lot of entries created for sharing purposes, I'd create a scheduled task to clean up the data store from obsolete entries.
I know this is a very old question, but I just want post solution I worked around
Below will hold data per http request basis.
HttpContext.Current.Items["ModuleInfo"] = "Custom Module Info"
we can store data to httpcontext in one sitecore pipeline and retrieve in another...
https://www.codeproject.com/Articles/146455/When-Can-We-Use-HttpContext-Current-Items-to-Store

Ember Data Sync - LocalStorage+REST+RealTime+Online/Offline

We have a combination of requirements in terms o data access.
Pre-load some reference data.
We need reference data to survive browser restarts instead of just living in memory to avoid loading it all the time. I'm currently using the LocalStorageAdapter for that.
Once we have it, we would like to sync changes (polling or using Socket.IO in the background and updating the LocalStorage could do the trick)
There're other models that are more transactional, where we would need to directly go to the Server and get/save them. It would be nice to use something like the RESTAdapter for that.
Lastly, there're some operations that should work off-line and changes should be synced later.
To make it more concrete:
We pre-load vendor and "favorite products" into Local Storage. We work offline with those.
We need to sync server changes to vendor and product information.
If they search the full catalog, that requires them to be online.
When offline, we need to allow users to add something to their cart or even submit and order. We would like to queue this action and submit it when they have an Internet Connection.
So a few questions are derived from this:
Is there a way to user RESTAdapter in combination with LocalStorage?
Is there some Socket.IO support? (Happy to do this part manually)
Is there Queueing support? Ideally at the Ember-Data level.
I know we will have to do a lot of this manually and pull together the different lego pieces, but I wanted to ask for some perspective from experience Ember devs.
You definitely can do this. Like you said you're going to need to do a lot of lego pieces to put it all together.
You'll need to take the RESTAdapter and LSAdapter and create a hybrid. We've done something a little similar at my work, but it only goes one way (from server to client, not reverse).
That being said, I'd just like to pose a few questions:
How much do you plan on storing in localStorage, and do you have an eviction plan in place? Local Storage is generally small for most browsers, though the implementation is the same across most browsers (not implemented until IE8). IndexedDB gives you a much larger chunk of space, though implementation isn't available until later versions of IE.
Depending on performance needs, I'd recommend storing localStorage first, then attempting to persist to the server, if that works pop from localStorage, if it doesn't leave it in there for your adapter to attempt at a later date. (I'd look into using Ember's schedule or scheduleOnce or a slew of other convenient helpers that work within the run loop, http://emberjs.com/api/classes/Ember.run.html#method_schedule).
Called by the store when a newly created record is
`save`d.
It serializes the record, and `POST`s it to a URL generated by `buildURL`.
See `serialize` for information on how to customize the serialized form
of a record.
createRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record, { includeId: true });
// build up a model that knows the url, the method, and the data to post
// store it to local storage in some queue to save
// schedule it to save to server later, keep track of the record since you'll
// need to update the record with new information later that could come down
// from the server
return this.ajax(this.buildURL(type.typeKey), "POST", { data: data });
},
Honestly I think the most difficult thing you might experience will be how you handle ids when you don't really save it to the server. Good luck

How can I design a ColdFusion page to update an Array of data across requests without using the SESSION scope?

This is more of a conceptual question. I have a working application that allows users to upload a CSV file of addresses, then parses the data into an Array of Address objects, then validates each Address object against certain rules (certain fields are required, etc.). The page then displays any addresses that failed validation, giving the user the ability to edit or delete each.
Right now, I am storing the entire Array in a SESSION variable, assigning each Address an Id value, then updating each Address in the SESSION Array when the user makes edits and submits the form.
I'm trying to think of a way to do this without using the SESSION scope, or using a physical database, or physical file. Any ideas?
If you don't use a physical database you would have to use some sort of persistent scope. That means the SESSION scope, the CLIENT scope (if you have that enabled), the APPLICATION scope, or the SERVER scope. But I think the safest way (as all those persistent scopes are cleared if your server goes down) is to store them in a database -- whether that database is a RDBMS, text file, or a Verity or Solr collection. I apologize in advance if that doesn't answer your question.
The data needs to be stored / preserved somewhere if you want to work with it across multiple requests. Aside from the options your question rules out (session, database, file), I can think of two other (non-ideal) options:
External cache mechanism like memcached -- not necessarily recommended because it's inherently volatile and doesn't guarantee to preserve your data
Pass the contents of the CSV around from request to request, e.g. via hidden FORM containing JSON -- not recommended if the CSV can get large
Personally, my colleagues and I tend to use temporary database storage for this type of issue.
I don't know anything about your requirements or use cases, but if you can depend on your users to have modern browsers, another viable option might be HTML5 localStorage.
Skimming some of the localstorage questions might give you some ideas.

read objects persisted but not yet flushed with doctrine

I'm new to symfony2 and doctrine.
here is the problem as I see it.
i cannot use :
$repository = $this->getDoctrine()->getRepository('entity');
$my_object = $repository->findOneBy($index);
on an object that is persisted, BUT NOT FLUSHED YET !!
i think getRepository read from DB, so it will not find a not-flushed object.
my question: how to read those objects that are persisted (i think they are somewhere in a "doctrine session") to re-use them before i do flush my entire batch ?
every profile has 256 physical plumes.
every profile has 1 plumeOptions record assigned to it.
In plumeOptions, I have a cartridgeplume which is a FK for PhysicalPlume.
every plume is identified by ID (auto-generated) and an INDEX (user-generated).
rule: I say profile 1 has physical_plume_index number 3 (=index) connected to it.
now, I want to copy a profile with all its related data to another profile.
new profile is created. New 256 plumes are created and copied from older profile.
i want to link the new profile to the new plume index 3.
check here: http://pastebin.com/WFa8vkt1
I think you might want to have a look at this function:
$entityManager->getUnitOfWork()->getScheduledEntityInsertions()
Gives you back a list of entity objects which are persisting yet.
Hmm, I didn't really read your question well, with the above you will retrieve a full list (as an array) but you cannot query it like with getRepository. I will try found something for u..
I think you might look at the problem from the wrong angle. Doctrine is your persistance layer and database access layer. It is the responsibility of your domain model to provide access to objects once they are in memory. So the problem boils down to how do you get a reference to an object without the persistance layer?
Where do you create the object you need to get hold of later? Can the method/service that create the object return a reference to the controller so it can propagate it to the other place you need it? Can you dispatch an event that you listen to elsewhere in your application to get hold of the object?
In my opinion, Doctrine should be used at the startup of the application (as early as possible), to initialize the domain model, and at the shutdown of the application, to persist any changes to the domain model during the request. To use a repository to get hold of objects in the middle of a request is, in my opinion, probably a code smell and you should look at how the application flow can be refactored to remove that need.
Your is a business logic problem effectively.
Querying down the Database a findby Query on Object that are not flushed yet, means heaving much more the DB layer querying object that you have already in your function scope.
Also Keep in mind a findOneBy will retrieve also other object previously saved with same features.
If you need to find only among those new created objects, you should make f.e. them in a Session Array Variable, and iterate them with the foreach.
If you need a mix of already saved items + some new items, you should threate the 2 parts separately, one with a foreach , other one with the repository query!