How to prevent malfunction (memory leak) by disposing static methods? - c#

I am using ASP.NET 4.0.
From last few weeks, few users are complaining that the application starts malfunctioning. The GridView suddenly starts showing contents of a DropDown control that the same user or another concurrent user might have accessed at any point of time in that day. Similarly, DropDown controls may get populated by RowID of the any old result-set instead of the actual items.
I came across an article: Users seeing other users data in ASP.NET where the author discusses about Static objects responsible for memory leak behavior.
It reminds me of a class in my project which is Static and contains public static methods. This class contains methods to populate a DropDown, return a DataSet for a query input or return a scalar object based on a query input.
Extract of this class is below:
public static class reuse
{
public static void FillDropDownList(string Query, DropDownList DropDownName, string ConnectionStringParameter)
{
SqlDataReader dr;
try
{
dbConnection.OpenConnection(ConnectionStringParameter);
//Check whether the Drop Down has existing items. If YES, empty it.
if (DropDownName.Items.Count > 0)
DropDownName.Items.Clear();
SqlCommand cmd = new SqlCommand(Query,dbConnection.cn);
dr = cmd.ExecuteReader();
DropDownName.Items.Add("-- Select --");
DropDownName.Items.Add("All");
while (dr.Read())
DropDownName.Items.Add(dr[0].ToString());
dr.Close();
}
catch (Exception ex)
{
rpkCustomErrorHandler.GetScript(HttpContext.Current.Response,ex.Message.ToString());
}
dbConnection.CloseConnection();
}
}
I want to know whether this is the cause of the malfunction I discussed above. If yes, is there any way to dispose Static Methods after the task of the method has finished. Do I need to change the class from Static to a default plain class?
Edited
I have another class which is also static and is used by the above class:
public static class dbConnection
{
public static SqlConnection cn = new SqlConnection();
public static void OpenConnection()
{
try
{
cn.ConnectionString = ConfigurationManager.ConnectionStrings["cnWebTwDrill"].ToString();
if (cn.State == ConnectionState.Closed)
cn.Open();
}
catch (Exception)
{
throw;
}
}
}
Shall I remove "Static" from the Connection Class and make call to this class by using a unique instance each time?

The code you've shown us is an example of bad usage of static class/method. You put in a static method or class things that are to simple to fit in an object AND which DON'T REQUIRE state.
The functionality you have there should be split between the Business Layer (which will retrieve the data) and the UI/COntroller (in this case Page ) where you assign the data to the server control. All this operations are specific to a request, there is no reason to use a static method for that. Is just a sign of (bad) procedural programming. And when dealing with db access (or disposable objects) you should use the using statement. Something like this
using(var conex=GetConnection())
{
try
{
conex.Open();
//do stuff
var cmd= new SqlCommand();//cfg command
using (var rd= cmd.ExecuteReader())
{
//do read
}
}
catch(Exception ex)
{
//handle exception
}
}
The using statement automatically calls Dispose at the end of the block. It's basically a shortcut for
try {}
finally{ //dispose }.

Its not a question of leaking or disposing its a question of utilizing static objects with state. This function is static, but it is not statefull all of the context of the operation is present in the call as such all of the objects in this class that are not parameters will be cleaned up automatically. However if you defined some type of static data any users in the same app domain would share the value. That being said you must be carefully any time you utilize statics as they are hard to test replace and are very difficult in multithreading situations.

I doubt the error you're seeing is caused by a memory leak or a failure to Dispose of static objects.
However, to answer your question: the only way to free the memory held by static objects is to set the associated static references to null. After that, they won't be reachable, and the GC will take care of the rest.
Two things that might help with the actual problem:
Faulty caching strategies can cause unintentional data sharing (at the HTTP level or with the ASP.NET object cache, output caching, etc)
Be sure to use locking around all references to static objects that can be shared between threads, where one thread might write the object while another is reading it.
BTW, the static method in the OP does not appear to use any static objects; everything it touches seems to be passed as an argument. Static methods alone don't allocate or hold memory references.
Update:
Trying to share a single DB connection between page requests is a bug, and will almost certainly result in undefined behavior (for example, one page could issue a query, while another page reads the response). DB connections are already pooled by the runtime; you don't need to optimize that part on your own. Each page request should not only use a new SqlConnection, it should also call Dispose() on the connection object afterwards, to promptly release it back to the pool.

Related

Use static class in ASP.NET Web API

I am posting this question using an automatic translation.
Please forgive any grammatical errors.
I have built an application using the .NET framework and the ASP.net Web API.
I have split the virtual path for each customer region within a site running on IIS and copied the same binary to run as separate applications.
The applications run in the same application pool.
Recently, some customers have been making a very large number of requests in a matter of minutes.
(I suspect a glitch in the system on the customer's end).
I am thinking of adding a static class to my current application that keeps track of the number of requests per customer in a given time period and blocks them if the threshold is exceeded.
From past StackOverFlow articles I have found that "information in the static class is lost if the application pool is recycled", but I have determined that this is not a problem in this case.
For my purposes, I only need to be able to retain information for a few minutes.
However, I still have a few questions that I can't find answers to, so I'd like to ask you all a few questions.
Even if the same binary is running in the same application pool, will the static class information be kept separately for different applications?
Will the static constructor of a static class be executed even after the application pool is recycled?
Is there a problem if I reference a field in Global.asax from within a static class?
Is there a problem with referencing the contents of web.config from within a static class?
Attached below is the source of my experimental implementation.
I plan to call the static method "ExcessiveRequestCheck.isExcessiveRequest" of this static class after the Web API receives the request and identifies the user ID.
Any advice would be sincerely appreciated.
P.S.
I understand that this approach does not work well in a load balancing environment. Currently my system only runs on one virtual machine. If you are moving to the cloud or deploying a load balancer, you will probably need a different approach than this one.
public static class ExcessiveRequestCheck
{
private static Dictionary<string, ExcessiveRequestInfo> dicExcessiveRequestCheckInfo = new Dictionary<string, ExcessiveRequestInfo>();
private static object initLock = new object();
private static object dicExcessiveRequestCheckInfoLock = new object();
//If possible, I want this process to be a static constructor
public static Dictionary<int, int> dicExcessiveRequestSkipConditions
{
get
{
lock (initLock)
{
if (ExcessiveRequestCheck._dicExcessiveRequestSkipConditions == null)
{
//if possible, I want to set this value from Web.config.
ExcessiveRequestCheck._dicExcessiveRequestSkipConditions = new Dictionary<int, int>() {
{ 5, 3 }, { 15, 5 }, { 45, 10 }, { 120, 20 }
};
}
return ExcessiveRequestCheck._dicExcessiveRequestSkipConditions;
}
}
}
private static Dictionary<int, int> _dicExcessiveRequestSkipConditions = null;
public const int BUFFER_CLEAR_MINUTES = 5;
public static bool isExcessiveRequest(string userId)
{
ExcessiveRequestCheck.refreshExcessiveRequestCheckInfo();
lock (ExcessiveRequestCheck.dicExcessiveRequestCheckInfoLock)
{
if (ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.ContainsKey(userId) == false)
{
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.Add(userId, new ExcessiveRequestInfo() { countRequest = 1 });
return false;
}
bool doSkip = false;
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].countRequest++;
foreach (KeyValuePair<int, int> pair in ExcessiveRequestCheck.dicExcessiveRequestSkipConditions)
{
if (ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].lastRequesttTime.AddSeconds(pair.Key) > DateTime.Now)
{
if (ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].countRequest > pair.Value)
{
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].wasRequestSkip = true;
doSkip = true;
}
}
}
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[userId].lastRequesttTime = DateTime.Now;
return doSkip;
}
}
public static void refreshExcessiveRequestCheckInfo()
{
lock (ExcessiveRequestCheck.dicExcessiveRequestCheckInfoLock)
{
var keyList = ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.Keys;
foreach (string key in keyList)
{
if (ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.ContainsKey(key))
{
var value = ExcessiveRequestCheck.dicExcessiveRequestCheckInfo[key];
if (value.lastRequesttTime.AddMinutes(BUFFER_CLEAR_MINUTES) < DateTime.Now)
{
if (value.wasRequestSkip)
{
//this NLog instance was created in Global.asax.cs
WebApiApplication.logger.Fatal("skip request! user id=" + key);
}
ExcessiveRequestCheck.dicExcessiveRequestCheckInfo.Remove(key);
}
}
}
}
}
}
class ExcessiveRequestInfo
{
public DateTime requestStartTime { get; set; } = DateTime.Now;
public DateTime lastRequesttTime { get; set; } = DateTime.Now;
public int countRequest { get; set; } = 0;
public bool wasRequestSkip { get; set; } = false;
}
Your questions
Even if the same binary is running in the same application pool, will the static class information be kept separately for different applications?
Yes, they are separate
Will the static constructor of a static class be executed even after the application pool is recycled?
Yes, the static constructor is guaranteed to be called before any of the static methods are executed
Is there a problem if I reference a field in Global.asax from within a static class?
No more than accessing it from anywhere else
Is there a problem with referencing the contents of web.config from within a static class?
No more than accessing it from anywhere else
Your general approach
DoS
If you're trying to mitigate a denial-of-service attack or credential stuffing attack, your approach probably won't work, since requests to your service will still result in load being added to your server, and if they are performing a credential stuffing attack, it'll fill up your dictionary with millions of entries and possibly cause your application to crash.
If you want to mitigate a denial-of-service attack effectively, you will probably need a more network-oriented solution, such as a smart firewall or a WAF.
Rate limiting
If on the other hand you are attempting to throttle specific users' activities (i.e. rate limiting), again, your approach probably isn't the greatest, because it does not support load balancing-- your list is held in in-process memory. For per-user rate limiting you will probably need to track user activity in a central data store accessible to all of your servers.
Static constructors
As a general rule, you should try to avoid static constructors, or keep them very simple, as a failure in a static constructor will cause your entire application to fail to start. Be careful!
even if the same binary is running in the same application pool, will the static class information be kept separately for different applications?
If by different applications, you mean separate web sites? yes, it will be kept separate to each web site you have running for that app pool.
Will the static constructor of a static class be executed even after the application pool is recycled?
Hum, that's a bit confusing. The constructor will only be executed if you call the class and that given constructor. Since there is never a instance of the class created, then the "initialize/new" event is never used nor triggered. So, any method with parameters will run and work fine - including the constructor. I would suggest that there is not some "event" that gets triggered on first use - it would not and does not make sense in the context of a static class, since you never create an instance. So, if you have some methods with parameters then fine.
So, constructor in the context of new instance of the class makes no sense - (did not even think that is possible with static).
There is no concept of "new" event that triggers, so I fail to see how this issue can ever matter.
Is there a problem if I reference a field in Global.asax from within a static class?
Well, values in that class are global to ALL users. But, those values can go out of scope just about any old time you please. As a result, ZERO use of public members is practial. While a app-pool re-start will re-set those class values? They can go out of scope just about any old time. They are global to all and every user. So, persisting values, or attempting to persit values in a static class is NOT a viable choice for production code. You can have methods (code) in that class, but any public persisting values really can't be relied upon to persist correctly. I'm not 100% sure, but even just general .net garbage collection would likely cause a re-set.
If you need this information to persist, then you can't use static, you have to create a instance of that class and persist it in session(). And session is per user.
A static class public values will apply to EVERY user - not just the current user. In effect those values are global to all users - but without any real ccontrol or garrutee that the values will persit - you have no control over this and thus you can't adopt this concpet and design for any system of practial value.
Is there a problem with referencing the contents of web.config from within a static class?
Reading values? No problem. Update or modify values? - a MASSIVE different issue. You modify web.config, that will trigger a app pool restart.
So, you free to read any file - text files, xml or whatever, and that includes web.config. As long as you not modify such files, then no problems.
The main issue here?
It simple not practical to assume, or build a design in which public static class values are to persist. The ZERO control you have when such values may go out of scope is somthing you have ZERO control over, and thus such designs can't use nor rely on values persisting.
And of course on many web hosting systems? They are now adopting cloud computing. This means from one post back to the next, you might be using a different server, and again, that means such values can't persist in memory, since from one post-back to the next, or one web service call to the next? You may well be hitting a different server anyway (and they don't share memory) (so, this suggests say using SQL server based sessions, or at the very least persisting such values in a database).
In fact, if you need such persisting values and data? Then use a database. The WHOLE idea of web based software is you do NOT have state between post-backs. And you are attempting to go even down a worse road, but hope on a wing and a prayer that some global values "might" and "sort of" and "maybe" will persist between calls to the web site.
Answer:
You really can't do this with any realm of reliably.
So, most of your questions don't really matter. What matters is these values are to persist, and you can't rely on such a design. If you need some persisting values, then you have to adopt a system and design that supports that concept (viewstate, cookies, or session()).
Now, I suppose you can give this a try, and then come back with a detailed report and how your experience turned out. But, there are too many pit falls, and without any code or system control over persisting values in memory, I don't think I would go down this road.
In web land, it makes next to no sense to have public variables that you attempt to persist in a static class. You can have code, you can have cool methods, you can use session(). But, the concept of persisting values in static class is a design choice that does not make sense, and can't be relied upon.
Web software is assumed to be state-less, and that VERY much is the assumption you have to make in regards to a static class, or in fact general use of such code.

C# Close() or using/Dispose() frequently used SQLite object

Sometimes I see people like to dispose just anything after use regardless of how frequently they're being used (probably not related to SQLite question, but I am dealing with SQLite as of now, I'm puzzled) -- or perhaps I am mistaken. This has caused a massive confusion for me.
For example (taken from elsewhere):
using(var con = new SQLiteConnection(conString))
using(var cmd = new SQLiteCommand(con))
{
con.Open();
// ...
} // also closes the connection
My question is, should I store the SQLiteConnection and SQLiteCommand objects in the field, and use the method .Open(), .Close() to handle the database connection without disposing them at all until application termination -- or dispose them into the Garbage Collection like it's not really an elegant idea in my perspective?
Edit: If one says dispose, then why? I need better answers, I need the true reason why, not because of pooling, and whatnot. I need to know what exact problems could arise other than human-prone errors, and provide an example or perhaps a link to the example.
For example the class field:
private static SQLiteConnection sQLiteConnection; /// <summary>SQLiteConnection.</summary>
public static SQLiteConnection SQLiteConnection { get { return sQLiteConnection; } }
private static SQLiteCommand sQLiteCommand; /// <summary>SQLiteCommand.</summary>
public static SQLiteCommand SQLiteCommand { get { return sQLiteCommand; } }
Where the private fields are initialized with a private method, and the objects are to be reused without disposing them; Hence the read-only properties.
Edit 2: For clearer clarification, are you people misreading? I am saying "reusing". Which means one is created, and stored somewhere in the field to be reused. I am storing it in the static field in a static class to be reused until the application is closed. Tell me, why do I have to dispose it?
Why, do, I, have, to, dispose, it? If, I, were, to, "reuse", it? Why?
Connections are pooled by .NET, so creating them generally isn't an expensive operation. Using the "standard" approach is generally much cleaner that trying to keep track of if a connection is open or closed, etc.
Unless you have measurable problems with connection I would stick with the idomatic approach of creating them, using them, and disposing of them.

Possible performance issues with C# code in a legacy project

I started working recently in a new project where we have thousands of lines of legacy code. We are facing several performance issues. I decided to take a look at the code and saw the following. There's a class:
public class BaseDataAccess
{
private Database dB;
public Database DB
{
get
{
if (dB == null)
{
dB = DatabaseFactory.CreateDatabase();
}
return dB;
}
}
}
And many descendant classes which inherit from the previous base class. Internally, those other classes make use of the DB property, like this:
DataSet ds = DB.ExecuteDataSet(spGetCustomersSortedByAge);
Finally, there's a huge class (5000 lines of code) with tens of methods like the following:
public void ProcessPayments()
{
try
{
List<Employee> employees = new EmployeesDA().SelectAll(null);
foreach (Employee employee in employees)
{
employee.Account = new MovementsDA().SelectAll(employee.Id, DateTime.Now);
...
City city = new CitiesDA().Select(zone.cityId);
...
Management m = new ManagmentDA().Select(city.id);
}
}
catch (Exception ex)
{
...
}
}
Note in the previous method EmployeesDA, MovementsDA, CitiesDA and ManagmentDA all are inheritors of BaseDataAccess and internally use their respective DB properties. Also note they are constantly being instantiated inside foreach loops (many times within 2 levels of nesting).
I think the instantiation itself is suspicious but I'm more concerned about what's going on with the database connections here? Is every DA instantiated opening a new underlying connection? How bad is this code?
As a side note about the solution I was considering in case this code should be fixed: I was considering making every constructor private so the compiler starts complaining about the instantiations and refactor the instantiations with calls to the GetInstance method (singleton pattern) to avoid the recreation of the objects and underlying connections. But, I'm not sure if this could also be dangerous in some way, for example, if the connections may get closed. The current code doesn't have that problem because of the instantiatons happening all the time.
It's a common misconception that object construction is expensive. It's much more expensive than base arithmetic or other machine-level things, but isn't likely the direct source of performance issues.
Using boxed integers for a loop is wasteful for example, but constructing an Employee object in each vs reusing a mutable Employee object isn't going to give meaningful performance advantages.
Many garbage collectors are capable of object memory frame reuse in loops like this. In effect a single object frame is allocated and overwritten on each pass of the loop.
In this specific case there may be a cost if the DA's have significant initialization costs. If that is the case I would refactor the code to create those once outside the loop. I would not use actual static singletons. I would use dependency injection to manage singleton objects if you need it. Static singletons are effectively global variables and are an invitation to stateful coupling and the break down of modularity.

C# using statement cache

It must be a very dump question but I am wondering if I can use a cached object as part of the using statement
e.g
using(Class1 sample = Cache.GetClass<Class1>())
Cache.class is a static class which uses memoryCache to store a copy of Class1, and the GetClass is to get a copy of the stored object from cache if it is already there.
In my real life (almost, but simpilfied) exmaple, I have got this:
using (dataDesignerClass dds = Cache.GetClass<dataDesignerClass>()){
...
Dataset ds = new Dataset();
dds.dataadapter1.fill(ds); //dds is the data designer which contains all the sqlconnection, sql commands, adapters..etc which can get quite big
...
}
..which seems to be ok to me, but I find that SOMETIMES the dataset (ds) is not filled by the dataadapter1, without returning error.
My GetClass static class:
public static T GetClass<T> () where T: class
{
string keyName = "CACHE_" + typeof(T).Name.ToUpper();
CacheItem cacheItem = null;
cacheItem = GetCache(keyName); //a function to return the cache item
if (cacheItem == null)
{
T daClass = Activator.CreateInstance(typeof(T)) as T; //the constructor will call the initilalization routine
AddCache(keyName, daClass);
return daClass;
}
return (T)cacheItem.Value;
}
Can someone explain why it fails?
I think it is a bad idea to use using on something you cache.
The idea behind using is that it disposes all unmanaged memory allocation and handles an object has before it is destructed. You should not use your object after it is disposed. The problem here is it is not your intention to destruct and get rid of the object, hence you save it in a cache!
Also, a DataReader is somewhat of a cursor typed object. It will not like you for reusing it, especially when you use more than one thread.
Disposing the object will most likely break your software and give unexpected and unwanted result. Don't use using in this scenario.
Reusing a shared object is sometimes good practice, but you need to make sure it can be reused. In your program, you are storing a data adapter in the cache and trying to reuse it between different threads, that causes strange results sometimes because the data adapter can't be shared. Imaging two threads get a same instance of your adapter and modify it at the same time! IMO the data adapter is quite lite and you can create a new instance for each db read, it's unnecessary to cache and reuse it, that makes things complex.

Best Practice for storing data in an ASP.NET web page

I have a multi-user set of ASP.NET web pages. The pages use AJAX update panels so I can avoid updating the screen on every postback.
The lifecycle of each page is as follows:
1. During Page_Load, get relevant data for user from a web service.
2. Store the data (quite large), and a service reference in a static dataset.
3. allow various edits to parts of the data via the screen controls (grids, text boxes)
4. validate data captured via form
5. send updated data back to service
I am doing this using static variables in the Page class itself as follows:
public partial class MyPage : System.Web.UI.Page
{
static xxxx.DataCaptureServiceClient m_Service; //reference to web service
static string m_PersonID = string.Empty; //current person_id page is viewing
static ServResponse m_ServiceResult = null; // reference to our data to edit ( ServResponse is a large data contract)
static string m_SortExpression = "Reference"; //default sort expression for grid
const int PERSONID_COLUMN = 0; //column index in grid for the personID column
const int STATUS_COLUMN = 4; //column index in grid for the application status
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!Page.IsPostBack)
{
// Get new service instance.
m_Service = new xxxx.DataCaptureServiceClient();
ShowDataOnPage(); //get data in m_ServiceResult and bind to a grid on screen
}
}
catch (Exception ex)
{
Response.Redirect("ErrorPage.aspx", false);
}
}
protected void butNext_Click(object sender, EventArgs e)
{
try
{
Page.Validate();
if (Page.IsValid)
{
// Use m_ServiceResult and m_Service to send a packaged submission to the service.
SendDatatoService();
Response.Redirect("TheNextPage.aspx", false);
}
}
catch (Exception ex)
{
Response.Redirect("ErrorPage.aspx", false);
}
}
//Other methods which allow edits to m_ServiceResult
I am wondering if:
A) This is a good way to implement or are there better practices?
B) Should I clear down memory by setting all statics to NULL when I redirect to another page?
C) If I clear down the statics do I risk another user losing data?
UPDATE
I have rewritten removing the statics, keeping the const values and passing data I need around as parameters. Where I need to keep data for updates I have kept the minimal amount I need in session[] variables.
A) No - what happens if a 2nd user opens a page while another one is busy? The static dataset will be overwritten with the 2nd user's data, or is your static dataset somehow differentiating different users' data at the same time?
B) If you absolutely must use statics / server side data, then yes, you should clear them somehow. Guaranteeing that this happens is difficult however. (E.g. if one user just closes their browser)
C) Possibly, but if this is a concern then my question in A) is already going to cause greater problems for you.
As a general answer, storing large amounts of data in memory on the server is generally bad practice. It does not scale well, and opens you up for many different types of errors. Your back-end should be stateless, and there are a number of ways you could achieve that, for example storing the records in a separate table in the DB, which only get finalised (and thus moved into the "real" tables) at the end of the several screens you have.
In direct answer to your questions, without opening a can of worms
A) There is pretty much no worse way to implement data capture
B) Setting variables to null in .NET does not clear down memory.
C) Yes, yes you do. By definition every user is sharing the same static data.
I would keep your service delcarations local, and only use global variables for the constants. You're not saving much by declaring them globally. Also, I would use a const string instead of a static string.
I think the others have answered your questions. My suggestion to help fix your code would be to do some of the following:
m_PersonID should not be static - keep it an instance property/field of the page and have it as static. In fact, class-level variables in code behind can lend itself to fairly unreadable code very quickly. Does it really need to be class-level, or can it be defined in the method where you need it (and just, perhaps, passed as an argument to other methods)?
m_ServiceResult - same for this. Not sure why you have it, and it doesn't need to be static. Try to move it to a method-level variable.
m_SortExpression could just be a const
m_Service - again, I don't see the need for this to be a static. If it's just a proxy to a service, I don't think you need to keep it in memory to avoid unnecessary overhead. I think they problems keeping it static far outweigh the small overhead of having the service client be a method-level variable.
In regards to the static dataset, you may want to consider caching the large result set, if the data is fairly static for the user. Or, really take a look at what you're returning and evaluate if you really need all that data. If you're performing calculations in the code-behind, that's probably not the best place for it. Consider your service layer as the place for those calculations (or the db if you have a lot of your logic in stored procs - not saying that's the place for it, but just acknowledging that it's a possibility).
Also, a dataset is pretty large and bulky. Do you need this structure, or is a set of streamlined entity objects more appropriate? This item pretty much goes with #5, since you really should evaluate how you're retrieving data, storing it and acting upon it. A dataset may be the quick and dirty answer, but usually it's not the efficient answer.
In short, dump the statics and move to private, method-level variables where possible. Try to reduce the amount of data you have coming back from the database. Consider methods that take parameters instead of using class-level and/or global variables.
I hope this helps. Good luck!

Categories

Resources